Repository: basketwill/Sysmon_reverse Branch: master Commit: 94fee5819853 Files: 99 Total size: 365.0 KB Directory structure: gitextract_0g68xkff/ ├── README.md ├── Sysmon/ │ ├── CDName.cpp │ ├── CDName.h │ ├── CDigitalSign.cpp │ ├── CDigitalSign.h │ ├── CEventLogger.cpp │ ├── CEventLogger.h │ ├── CMofDataParser.cpp │ ├── CMofDataParser.h │ ├── CSsymonEtw.cpp │ ├── CSsymonEtw.h │ ├── CSysmonDriverOpt.cpp │ ├── CSysmonDriverOpt.h │ ├── CSysmonMofData.cpp │ ├── CSysmonMofData.h │ ├── CSysmonUtil.cpp │ ├── CSysmonUtil.h │ ├── ReadMe.txt │ ├── Resource.h │ ├── Sysmon.cpp │ ├── Sysmon.h │ ├── Sysmon.rc │ ├── Sysmon.vcxproj │ ├── Sysmon.vcxproj.filters │ ├── Sysmon.vcxproj.user │ ├── stdafx.cpp │ ├── stdafx.h │ ├── targetver.h │ ├── undname.cpp │ ├── undname.h │ └── undname.idl ├── Sysmon.sln ├── Sysmon.suo └── Sysmon.sys/ ├── CDeviceExtension.cpp ├── CDeviceExtension.h ├── CDriverEntry.cpp ├── CDriverEntry.h ├── CReportRecord.cpp ├── CReportRecord.h ├── CSysmonControl.cpp ├── CSysmonControl.h ├── CSysmonDispatchEngine.cpp ├── CSysmonDispatchEngine.h ├── CSysmonIoControl.h ├── CSysmonMiniFltFilter.cpp ├── CSysmonMiniFltFilter.h ├── ReadMe.txt ├── Sysmon.sys.cpp ├── Sysmon.sys.vcxproj ├── Sysmon.sys.vcxproj.filters ├── Sysmon.sys.vcxproj.user ├── cpplib/ │ ├── CAssert.h │ ├── CAttachDevice.cpp │ ├── CAttachDevice.h │ ├── CDebug.cpp │ ├── CDebug.h │ ├── CDeviceObject.cpp │ ├── CDeviceObject.h │ ├── CDispatchEngine.cpp │ ├── CDispatchEngine.h │ ├── CDriverDispatch.cpp │ ├── CDriverDispatch.h │ ├── CDriverObject.cpp │ ├── CDriverObject.h │ ├── CEResource.cpp │ ├── CEResource.h │ ├── CErrorStatus.cpp │ ├── CErrorStatus.h │ ├── CFileObject.cpp │ ├── CFileObject.h │ ├── CFilterDevice.cpp │ ├── CFilterDevice.h │ ├── CIntNumber.cpp │ ├── CIntNumber.h │ ├── CIoStackLocation.cpp │ ├── CIoStackLocation.h │ ├── CIrp.cpp │ ├── CIrp.h │ ├── CListEntry.cpp │ ├── CListEntry.h │ ├── CMiniFltFilter.cpp │ ├── CMiniFltFilter.h │ ├── CNPagedLookaside.cpp │ ├── CNPagedLookaside.h │ ├── CPool.cpp │ ├── CPool.h │ ├── CString.cpp │ ├── CString.h │ ├── CSysmonBase.cpp │ ├── CSysmonBase.h │ ├── CUnicodeString.cpp │ ├── CUnicodeString.h │ ├── CVersion.cpp │ ├── CVersion.h │ ├── CppLib.cpp │ └── CppLib.h ├── stdafx.cpp ├── stdafx.h └── targetver.h ================================================ FILE CONTENTS ================================================ ================================================ FILE: README.md ================================================ # Sysmon_reverse逆向微软sysmon的源代码,逆向的版本是v8 原始产品 https://docs.microsoft.com/zh-cn/sysinternals/downloads/sysmon ================================================ FILE: Sysmon/CDName.cpp ================================================ #include "StdAfx.h" #include "CDName.h" CDName::CDName(void) { } CDName::~CDName(void) { } char* CDName::_unDName() { return NULL; } ================================================ FILE: Sysmon/CDName.h ================================================ #ifndef _CDName_H #define _CDName_H class CDName { public: CDName(void); virtual ~CDName(void); static char* _unDName(); }; #endif ================================================ FILE: Sysmon/CDigitalSign.cpp ================================================ #include "StdAfx.h" #include "CDigitalSign.h" CDigitalSign::CDigitalSign(void) :m_bInit(false) ,m_WinVerifyTrust(NULL) ,m_pWTHelperGetProvSignerFromChain(NULL) ,m_pWTHelperProvDataFromStateData(NULL) ,m_pCryptCATAdminReleaseContext(NULL) ,m_pCryptCATAdminReleaseCatalogContext(NULL) ,m_pCryptCATCatalogInfoFromContext(NULL) ,m_pCryptCATAdminEnumCatalogFromHash(NULL) ,m_pCryptCATAdminCalcHashFromFileHandle(NULL) ,m_pCryptCATAdminAcquireContext(NULL) ,m_pCryptCATAdminAddCatalog(NULL) ,m_pCryptCATAdminRemoveCatalog(NULL) ,m_pIsCatalogFile(NULL) ,m_pCertNameToStrW(NULL) { } CDigitalSign::~CDigitalSign(void) { } bool CDigitalSign::Init() { if (!m_bInit) { m_bInit = true; HMODULE hWinTrust = LoadLibraryW(L"Wintrust.dll"); if ( !hWinTrust ) return false; m_WinVerifyTrust = (pWinVerifyTrust)GetProcAddress(hWinTrust, "WinVerifyTrust"); m_pWTHelperGetProvSignerFromChain = (pWTHelperGetProvSignerFromChain) GetProcAddress(hWinTrust, "WTHelperGetProvSignerFromChain"); m_pWTHelperProvDataFromStateData = (pWTHelperProvDataFromStateData) GetProcAddress(hWinTrust, "WTHelperProvDataFromStateData"); m_pCryptCATAdminReleaseContext = (pCryptCATAdminReleaseContext) GetProcAddress(hWinTrust, "CryptCATAdminReleaseContext"); m_pCryptCATAdminReleaseCatalogContext = (pCryptCATAdminReleaseCatalogContext) GetProcAddress(hWinTrust, "CryptCATAdminReleaseCatalogContext"); m_pCryptCATCatalogInfoFromContext = (pCryptCATCatalogInfoFromContext) GetProcAddress(hWinTrust, "CryptCATCatalogInfoFromContext"); m_pCryptCATAdminEnumCatalogFromHash = (pCryptCATAdminEnumCatalogFromHash) GetProcAddress(hWinTrust, "CryptCATAdminEnumCatalogFromHash"); m_pCryptCATAdminCalcHashFromFileHandle = (pCryptCATAdminCalcHashFromFileHandle) GetProcAddress(hWinTrust,"CryptCATAdminCalcHashFromFileHandle"); m_pCryptCATAdminAcquireContext = (pCryptCATAdminAcquireContext) GetProcAddress(hWinTrust,"CryptCATAdminAcquireContext"); m_pCryptCATAdminAddCatalog = (pCryptCATAdminAddCatalog) GetProcAddress(hWinTrust, "CryptCATAdminAddCatalog"); m_pCryptCATAdminRemoveCatalog = (pCryptCATAdminRemoveCatalog) GetProcAddress(hWinTrust, "CryptCATAdminRemoveCatalog"); m_pIsCatalogFile = (pIsCatalogFile)GetProcAddress(hWinTrust, "IsCatalogFile"); hWinTrust = LoadLibraryW(L"crypt32.dll"); m_pCertNameToStrW = (pCertNameToStrW)GetProcAddress(hWinTrust, "CertNameToStrW"); } return m_pCryptCATAdminAcquireContext != 0; } ================================================ FILE: Sysmon/CDigitalSign.h ================================================ #ifndef _CDigitalSign_h #define _CDigitalSign_h #include typedef void* HCATINFO; typedef void* HCATADMIN; typedef struct CATALOG_INFO_ { DWORD cbStruct; WCHAR wszCatalogFile[MAX_PATH]; } CATALOG_INFO; extern "C" { typedef LONG ( WINAPI *pWinVerifyTrust)( HWND hwnd, GUID *pgActionID, LPVOID pWVTData); typedef CRYPT_PROVIDER_SGNR* (WINAPI *pWTHelperGetProvSignerFromChain)( CRYPT_PROVIDER_DATA *pProvData, DWORD idxSigner, BOOL fCounterSigner, DWORD idxCounterSigner); typedef CRYPT_PROVIDER_DATA * (WINAPI *pWTHelperProvDataFromStateData)( HANDLE hStateData); typedef BOOL (WINAPI *pCryptCATAdminReleaseContext)( IN VOID* hCatAdmin, IN DWORD dwFlags ); typedef BOOL (WINAPI *pCryptCATAdminReleaseCatalogContext)( IN VOID* hCatAdmin, IN VOID* hCatInfo, IN DWORD dwFlags ); typedef BOOL (WINAPI *pCryptCATCatalogInfoFromContext)( _In_ VOID* hCatInfo, _Inout_ CATALOG_INFO *psCatInfo, _In_ DWORD dwFlags ); typedef HCATINFO (WINAPI *pCryptCATAdminEnumCatalogFromHash)( HCATADMIN hCatAdmin, BYTE *pbHash, DWORD cbHash, DWORD dwFlags, HCATINFO *phPrevCatInfo ); typedef BOOL (WINAPI *pCryptCATAdminCalcHashFromFileHandle)( HANDLE hFile, DWORD *pcbHash, BYTE *pbHash, DWORD dwFlags ); typedef BOOL (WINAPI *pCryptCATAdminAcquireContext)( HCATADMIN *phCatAdmin, const GUID *pgSubsystem, DWORD dwFlags ); typedef HCATINFO (WINAPI *pCryptCATAdminAddCatalog)( HCATADMIN hCatAdmin, PWSTR pwszCatalogFile, PWSTR pwszSelectBaseName, DWORD dwFlags ); typedef BOOL (WINAPI *pCryptCATAdminRemoveCatalog)( IN HCATADMIN hCatAdmin, IN LPCWSTR pwszCatalogFile, IN DWORD dwFlags ); typedef BOOL (WINAPI *pIsCatalogFile)( IN HANDLE hFile, WCHAR *pwszFileName ); typedef DWORD (WINAPI *pCertNameToStrW)( DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, DWORD dwStrType, LPSTR psz, DWORD csz ); }; class CDigitalSign { public: CDigitalSign(void); virtual ~CDigitalSign(void); bool Init(); private: bool m_bInit; pWinVerifyTrust m_WinVerifyTrust; pWTHelperGetProvSignerFromChain m_pWTHelperGetProvSignerFromChain; pWTHelperProvDataFromStateData m_pWTHelperProvDataFromStateData; pCryptCATAdminReleaseContext m_pCryptCATAdminReleaseContext; pCryptCATAdminReleaseCatalogContext m_pCryptCATAdminReleaseCatalogContext; pCryptCATCatalogInfoFromContext m_pCryptCATCatalogInfoFromContext; pCryptCATAdminEnumCatalogFromHash m_pCryptCATAdminEnumCatalogFromHash; pCryptCATAdminCalcHashFromFileHandle m_pCryptCATAdminCalcHashFromFileHandle; pCryptCATAdminAcquireContext m_pCryptCATAdminAcquireContext; pCryptCATAdminAddCatalog m_pCryptCATAdminAddCatalog; pCryptCATAdminRemoveCatalog m_pCryptCATAdminRemoveCatalog; pIsCatalogFile m_pIsCatalogFile; pCertNameToStrW m_pCertNameToStrW; }; #endif ================================================ FILE: Sysmon/CEventLogger.cpp ================================================ #include "StdAfx.h" #include "CEventLogger.h" #include #pragma comment (lib, "strsafe.lib") CEventLogger::CEventLogger(void): m_hTrace(0), m_hSession(0), m_bLoggingEnabled(FALSE), m_nLoggingLevel(TRACE_LEVEL_INFORMATION) { memset( &m_provider_guid, 0, sizeof(m_provider_guid)); memset( &m_session_guid, 0, sizeof(m_session_guid)); } CEventLogger::~CEventLogger(void) { DeInit(); } /* Initialize the logger lpszLogFile: location of log file, must end with .etl and all folders in path must exists lpszSessionName: unique session name, like "_trace" */ HRESULT CEventLogger::Init( LPCTSTR lpszLogFile, LPCTSTR lpszSessionName, GUID *pguid) { HRESULT hr = S_OK; if(NULL == m_hTrace) { m_strLogFile = lpszLogFile; m_strSessionName = lpszSessionName; if(m_strLogFile.GetLength() > 0 && m_strSessionName.GetLength() > 0) { // if caller didnt supply a GUID we will create one on the fly if(NULL == pguid) hr = CoCreateGuid(&m_provider_guid); else memcpy_s( &m_provider_guid, sizeof(m_provider_guid), pguid, sizeof(GUID)); // register us as event provider hr = AtlHresultFromWin32( RegisterTraceGuids( &CEventLogger::ControlCallback, this, &m_provider_guid, NULL, NULL, NULL, NULL, &m_hTrace)); if(SUCCEEDED(hr)) { m_hSession = NULL; m_bLoggingEnabled = FALSE; m_nLoggingLevel = TRACE_LEVEL_INFORMATION; /** Initialize the structure that will be used for writing events, the structure looks like this: struct{ EVENT_TRACE_HEADER header; MOF_FIELD mof; } We will use only one MOF_FIELD after the EVENT_TRACE_HEADER and the logging text will be put here */ if(m_eventdata.GetCount() == 0) m_eventdata.SetCount(sizeof(EVENT_TRACE_HEADER) + sizeof(MOF_FIELD)); if(m_eventdata.GetCount() > 0) { memset(m_eventdata.GetData(), 0, m_eventdata.GetCount()); PEVENT_TRACE_HEADER pEventHeader = (PEVENT_TRACE_HEADER)m_eventdata.GetData(); pEventHeader->Size = m_eventdata.GetCount(); pEventHeader->Flags = WNODE_FLAG_USE_MOF_PTR; pEventHeader->Class.Type = EVENT_TRACE_TYPE_INFO; } hr = CoCreateGuid(&m_session_guid); m_sessiondata.SetCount( sizeof(EVENT_TRACE_PROPERTIES) + (m_strLogFile.GetLength() + m_strSessionName.GetLength() + 2) * 2); if(m_sessiondata.GetCount() > 0) { memset( m_sessiondata.GetData(), 0, m_sessiondata.GetCount()); PEVENT_TRACE_PROPERTIES pTracePropperties = (PEVENT_TRACE_PROPERTIES)m_sessiondata.GetData(); pTracePropperties->Wnode.BufferSize = m_sessiondata.GetCount(); pTracePropperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID; pTracePropperties->Wnode.ClientContext = 1; memcpy_s( &pTracePropperties->Wnode.Guid, sizeof(pTracePropperties->Wnode.Guid), &m_session_guid, sizeof(m_session_guid)); pTracePropperties->LogFileMode = EVENT_TRACE_FILE_MODE_CIRCULAR | EVENT_TRACE_USE_PAGED_MEMORY; pTracePropperties->MaximumFileSize = 1; pTracePropperties->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES); StringCchCopyW( (LPWSTR)((LPBYTE)pTracePropperties + pTracePropperties->LogFileNameOffset), m_strLogFile.GetLength() + 1, m_strLogFile.GetString()); pTracePropperties->LoggerNameOffset = pTracePropperties->LogFileNameOffset + (m_strLogFile.GetLength() + 1) * 2; StringCchCopyW( (LPWSTR)((LPBYTE)pTracePropperties + pTracePropperties->LoggerNameOffset), m_strSessionName.GetLength() + 1, m_strSessionName.GetString()); // start and enable trace hr = AtlHresultFromWin32( StartTrace( &m_hSession, m_strSessionName, pTracePropperties)); if(SUCCEEDED(hr)) { hr = AtlHresultFromWin32( EnableTrace( TRUE, 0, TRACE_LEVEL_VERBOSE, &m_provider_guid, m_hSession)); } } } } else { hr = E_INVALIDARG; } } return hr; } HRESULT CEventLogger::DeInit() { HRESULT hr = S_OK; if(NULL != m_hSession) { // Disable provider hr = AtlHresultFromWin32( EnableTrace( FALSE, 0, 0, &m_provider_guid, m_hSession)); // Stop trace hr = AtlHresultFromWin32( ControlTrace( m_hSession, m_strSessionName, (PEVENT_TRACE_PROPERTIES)m_sessiondata.GetData(), EVENT_TRACE_CONTROL_STOP) ); } if(NULL != m_hTrace) { // Unregister provider hr = AtlHresultFromWin32( UnregisterTraceGuids(m_hTrace)); m_hTrace = NULL; m_hSession = NULL; } return hr; } void CEventLogger::Log( UCHAR nLevel, LPCTSTR lpszFormat,...) { if(NULL != m_hSession && nLevel <= m_nLoggingLevel && m_eventdata.GetCount() > 0) { va_list args; va_start(args, lpszFormat); CString strLog; strLog.FormatV(lpszFormat, args); va_end(args); PEVENT_TRACE_HEADER pEventHeader = (PEVENT_TRACE_HEADER)m_eventdata.GetData(); PMOF_FIELD pMOF = (PMOF_FIELD)((LPBYTE)pEventHeader + sizeof(EVENT_TRACE_HEADER)); // Put the string as binary into the first the only MOF structure pEventHeader->Class.Level = nLevel; pMOF->Length = (strLog.GetLength() + 1) * sizeof(TCHAR); pMOF->DataPtr = (ULONG64)strLog.GetString(); // Write event HRESULT hr = AtlHresultFromWin32( TraceEvent( m_hSession, pEventHeader) ); } } ULONG CEventLogger::ControlCallback( WMIDPREQUESTCODE nRequestCode, PVOID pContext, ULONG* Reserved, PVOID pBuffer) { if(NULL != pContext) return ((CEventLogger*)pContext)->_ControlCallback( nRequestCode, (PWNODE_HEADER)pBuffer ); return ERROR_SUCCESS; } // Callback function which responses to logging control from ETW ULONG CEventLogger::_ControlCallback( WMIDPREQUESTCODE nRequestCode, PWNODE_HEADER pHeader) { if(WMI_ENABLE_EVENTS == nRequestCode) { m_bLoggingEnabled = TRUE; m_hSession = GetTraceLoggerHandle(pHeader); if(NULL != m_hSession) m_nLoggingLevel = GetTraceEnableLevel(m_hSession); } else if(WMI_DISABLE_EVENTS == nRequestCode) { m_bLoggingEnabled = FALSE; m_hSession = 0; } return ERROR_SUCCESS; } ================================================ FILE: Sysmon/CEventLogger.h ================================================ #ifndef _CEventLogger_h #define _CEventLogger_h #include #include #include #include #include #include class CEventLogger { public: CEventLogger(void); virtual ~CEventLogger(void); HRESULT Init( LPCTSTR lpszLogFile, LPCTSTR lpszSessionName, GUID *pguid = NULL); HRESULT DeInit(); void Log(UCHAR nLevel, LPCTSTR lpszFormat,...); protected: static ULONG WINAPI ControlCallback( WMIDPREQUESTCODE nRequestCode, PVOID pContext, ULONG* Reserved, PVOID pBuffer); ULONG _ControlCallback( WMIDPREQUESTCODE nRequestCode, PWNODE_HEADER pHeader); GUID m_provider_guid; TRACEHANDLE m_hTrace; TRACEHANDLE m_hSession; BOOL m_bLoggingEnabled; UCHAR m_nLoggingLevel; CAtlArray m_eventdata; GUID m_session_guid; CStringW m_strLogFile; CStringW m_strSessionName; CAtlArray m_sessiondata; }; #endif ================================================ FILE: Sysmon/CMofDataParser.cpp ================================================ #include "StdAfx.h" #include "CMofDataParser.h" #include "Sysmon.h" #include #include #define SeLengthSid( Sid ) (8 +(4*((SID*)Sid)->SubAuthorityCount)) #pragma comment (lib,"Ws2_32.lib") CMofDataParser::CMofDataParser(void) :m_pServices(NULL) { InitializeListHead(&m_ModDataList); } CMofDataParser::~CMofDataParser(void) { } CMofDataParser* CMofDataParser::Instance() { if ( !m_pServices) { if(FAILED(Connect( BSTR(_T("root\\wmi"))))) { return NULL; } } return this; } HRESULT CMofDataParser::Connect( BSTR bstrNamespace ) { HRESULT hr = S_OK; IWbemLocator* pLocator = NULL; hr = CoInitialize(0); hr = CoCreateInstance(__uuidof(WbemLocator), 0, CLSCTX_INPROC_SERVER, __uuidof(IWbemLocator), (LPVOID*) &pLocator); if (FAILED(hr)) { goto cleanup; } hr = pLocator->ConnectServer(bstrNamespace, NULL, NULL, NULL, 0L, NULL, NULL, &m_pServices); if (FAILED(hr)) { goto cleanup; } hr = CoSetProxyBlanket(m_pServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); if (FAILED(hr)) { m_pServices->Release(); m_pServices = NULL; } cleanup: if (pLocator) pLocator->Release(); return hr; } BOOL CMofDataParser::Parse( PEVENT_TRACE pEvent, CMofParseRes& Result ) { TCHAR ClassGuid[50] = {0}; SYSTEMTIME st = {0}; FILETIME ft = {0}; IWbemClassObject* pEventCategoryClass = NULL; CMofParseRes* pEventRes = NULL; PROPERTY_LIST* pProperties = NULL; DWORD PropertyCount = 0; LONG pPropertyIndex[30] = {0}; PBYTE pEventData = NULL; PBYTE pEndOfEventData = NULL; if (!Instance()) { return NULL; } StringFromGUID2( pEvent->Header.Guid, ClassGuid, sizeof(ClassGuid)); ft.dwHighDateTime = pEvent->Header.TimeStamp.HighPart; ft.dwLowDateTime = pEvent->Header.TimeStamp.LowPart; if (pEvent->MofLength <= 0) { return FALSE; } for ( LIST_ENTRY* pEntry = m_ModDataList.Flink; pEntry != &m_ModDataList; pEntry = pEntry->Flink) { CMofParseRes* pRes = CONTAINING_RECORD( pEntry, CMofParseRes, m_Entry); if (pRes) { if (pRes) { if (pRes->m_MofHeader.MofVsersion == pEvent->Header.Class.Version && pRes->m_MofHeader.MofType == pEvent->Header.Class.Type) { if (pEvent->Header.Guid.Data1 == pRes->m_MofHeader.MofGuid.Data1 && pEvent->Header.Guid.Data2 == pRes->m_MofHeader.MofGuid.Data2 && pEvent->Header.Guid.Data3 == pRes->m_MofHeader.MofGuid.Data3 && pEvent->Header.Guid.Data4[0] == pRes->m_MofHeader.MofGuid.Data4[0] && pEvent->Header.Guid.Data4[1] == pRes->m_MofHeader.MofGuid.Data4[1] && pEvent->Header.Guid.Data4[2] == pRes->m_MofHeader.MofGuid.Data4[2] && pEvent->Header.Guid.Data4[3] == pRes->m_MofHeader.MofGuid.Data4[3] && pEvent->Header.Guid.Data4[4] == pRes->m_MofHeader.MofGuid.Data4[4] && pEvent->Header.Guid.Data4[5] == pRes->m_MofHeader.MofGuid.Data4[5] && pEvent->Header.Guid.Data4[6] == pRes->m_MofHeader.MofGuid.Data4[6] && pEvent->Header.Guid.Data4[7] == pRes->m_MofHeader.MofGuid.Data4[7]) { Result = *pRes; return TRUE; } } } } } FileTimeToSystemTime( &ft, &st); SystemTimeToTzSpecificLocalTime( NULL, &st, &Result.m_MofHeader.MofLocal); pEventCategoryClass = GetEventCategoryClass( BSTR(ClassGuid), pEvent->Header.Class.Version); if (pEventCategoryClass) { pEventRes = GetEventClassPropertyList( pEventCategoryClass, pEvent->Header.Guid, pEvent->Header.Class.Version, pEvent->Header.Class.Level, pEvent->Header.Class.Type); pEventCategoryClass->Release(); pEventCategoryClass = NULL; if (pEventRes) { Result = *pEventRes; // if (GetPropertyList( // pEventClass, // &pProperties, // &PropertyCount, // pPropertyIndex )) // { // // pEventData = (PBYTE)(pEvent->MofData); // pEndOfEventData = ((PBYTE)(pEvent->MofData) + pEvent->MofLength); // // if ( PropertyCount ) // { // Result.m_MofProperty = new MOF_ITEM[PropertyCount]; // if (Result.m_MofProperty) // { // ZeroMemory( // Result.m_MofProperty, // sizeof(MOF_ITEM) * // PropertyCount); // } // } // // if ( Result.m_MofProperty ) // { // for (LONG i = 0; (DWORD)i < PropertyCount; i++) // { // // if ( !(0 <= pPropertyIndex[i] && // pPropertyIndex[i] <= PropertyCount )) // { // break; // } // // GetPropertyName( // &pProperties[pPropertyIndex[i]], // Result.m_MofProperty[i].Name); // // pEventData = GetPropertyValue( // &pProperties[pPropertyIndex[i]], // *(Result.GetItem(i)), // pEventData, // (USHORT)(pEndOfEventData - pEventData)); // // if (NULL == pEventData) // { // break; // } // // Result.m_MofHeader.MofCount = (i + 1); // } // } // // FreePropertyList( // pProperties, // PropertyCount); // } return TRUE; } } return FALSE; } IWbemClassObject* CMofDataParser::GetEventCategoryClass( BSTR bstrClassGuid, int Version) { HRESULT hr = S_OK; HRESULT hrQualifier = S_OK; IEnumWbemClassObject* pClasses = NULL; IEnumWbemClassObject* pClasses_2 = NULL; IWbemClassObject* pClass = NULL; IWbemClassObject* pClass_2 = NULL; IWbemQualifierSet* pQualifiers = NULL; ULONG cnt = 0; ULONG cnt_2 = 0; VARIANT varGuid; VARIANT varVersion; VariantInit(&varGuid); VariantInit(&varVersion); hr = m_pServices->CreateClassEnum( BSTR(_T("EventTrace")), WBEM_FLAG_DEEP | WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_USE_AMENDED_QUALIFIERS, NULL, &pClasses); if (FAILED(hr)) { goto cleanup; } __try { while (S_OK == hr) { if (pClass) { pClass->Release(); pClass = NULL; } hr = pClasses->Next(WBEM_INFINITE, 1, &pClass, &cnt); if (FAILED(hr) || cnt != 1) { goto cleanup; } VARIANT varCLassName; VariantInit(&varCLassName); if (FAILED(pClass->Get(BSTR(_T("__CLASS")),0,&varCLassName,0,0))) { continue; } m_pServices->CreateClassEnum( varCLassName.bstrVal, WBEM_FLAG_DEEP | WBEM_FLAG_UPDATE_ONLY | WBEM_FLAG_USE_AMENDED_QUALIFIERS, 0, &pClasses_2); VariantClear(&varCLassName); cnt_2 = 1; do { if (pClasses_2) { if ( pClasses_2->Next(5000, 1, &pClass_2, &cnt_2) != S_OK ) continue; if ( cnt_2 != 1 ) break; } else { pClass_2 = pClass; cnt_2 = 1; } HRESULT hr2 = pClass_2->Get(BSTR(_T("__CLASS")),0,&varCLassName,0,0); VariantClear(&varCLassName); if (SUCCEEDED(hr2)) { if ( pQualifiers ) { pQualifiers->Release(); pQualifiers = 0; } hrQualifier = pClass_2->GetQualifierSet(&pQualifiers); if (pQualifiers) { hrQualifier = pQualifiers->Get(L"Guid", 0, &varGuid, NULL); if (SUCCEEDED(hrQualifier)) { if (_wcsicmp(varGuid.bstrVal, bstrClassGuid) == 0) { hrQualifier = pQualifiers->Get(L"EventVersion", 0, &varVersion, NULL); if (SUCCEEDED(hrQualifier)) { VariantChangeType(&varVersion, &varVersion, 0, VT_I2); SHORT Ver = varVersion.iVal; VariantClear(&varVersion); if (Version == Ver) { __leave; //found class } VariantClear(&varVersion); } else if (WBEM_E_NOT_FOUND == hrQualifier) { __leave; //found class } } VariantClear(&varGuid); } pQualifiers->Release(); pQualifiers = NULL; } } if (pClass_2) { pClass_2->Release(); pClass_2 = NULL; } } while (cnt_2 == 1); if (pClasses_2) { pClasses_2->Release(); pClasses_2 = NULL; } } } __except(EXCEPTION_EXECUTE_HANDLER) { } cleanup: if (pClasses_2) { pClasses_2->Release(); pClasses_2 = NULL; } if (pClasses) { pClasses->Release(); pClasses = NULL; } if (pQualifiers) { pQualifiers->Release(); pQualifiers = NULL; } if (pClass) { pClass->Release(); pClass = NULL; } VariantClear(&varVersion); VariantClear(&varGuid); return pClass_2; } CMofParseRes* CMofDataParser::GetEventClassPropertyList( IWbemClassObject* pEventCategoryClass, GUID& Guid, USHORT Version, USHORT Level, USHORT EventType) { HRESULT hr = S_OK; HRESULT hrQualifier = S_OK; IEnumWbemClassObject* pClasses = NULL; IWbemClassObject* pClass = NULL; IWbemQualifierSet* pQualifiers = NULL; BOOL FoundEventClass = FALSE; CMofParseRes* pMofParseRes = NULL; OLECHAR szClassName[100] = {0}; ULONG cnt = 0; VARIANT varClassName; VARIANT varEventType; VARIANT varDisplayName; LIST_ENTRY pList; InitializeListHead(&pList); VariantInit(&varClassName); VariantInit(&varEventType); VariantInit(&varDisplayName); hr = pEventCategoryClass->Get(_T("__CLASS"), 0, &varClassName, NULL, NULL); if (FAILED(hr)) { goto cleanup; } StringCchCopy( szClassName, 100, varClassName.bstrVal); if (pQualifiers) { pQualifiers->Release(); pQualifiers = NULL; } pEventCategoryClass->GetQualifierSet(&pQualifiers); if (pQualifiers && !pQualifiers->Get( BSTR(_T("DisplayName")), 0, &varDisplayName, 0) && varDisplayName.lVal ) { StringCchCopy( szClassName, MAX_PATH, varDisplayName.bstrVal); } hr = m_pServices->CreateClassEnum(varClassName.bstrVal, WBEM_FLAG_DEEP | WBEM_FLAG_UPDATE_ONLY | WBEM_FLAG_USE_AMENDED_QUALIFIERS, NULL, &pClasses); if (FAILED(hr)) { goto cleanup; } while (S_OK == hr) { hr = pClasses->Next(WBEM_INFINITE, 1, &pClass, &cnt); if (hr != S_OK) { goto cleanup; } if (cnt != 1) { break; } if (pQualifiers) { pQualifiers->Release(); pQualifiers = NULL; } hrQualifier = pClass->GetQualifierSet(&pQualifiers); if (FAILED(hrQualifier)) { pClass->Release(); pClass = NULL; goto cleanup; } hrQualifier = pQualifiers->Get(L"EventType", 0, &varEventType, NULL); if (FAILED(hrQualifier)) { pClass->Release(); pClass = NULL; goto cleanup; } // If multiple events provide the same data, the EventType qualifier // will contain an array of types. Loop through the array and find a match. if (varEventType.vt & VT_ARRAY) { HRESULT hrSafe = S_OK; SAFEARRAY* pEventTypes = varEventType.parray; VARIANT vargTypeName; VariantInit(&vargTypeName); if ( pQualifiers->Get( BSTR(_T("EventTypeName")), 0, &vargTypeName, 0) == S_OK && vargTypeName.vt & VT_ARRAY ) { SAFEARRAY* pEventNames = vargTypeName.parray; BSTR* ppvData = NULL; if (pEventNames && pEventTypes && pEventNames->rgsabound->cElements && pEventTypes->rgsabound->cElements && pEventTypes->rgsabound->cElements == pEventNames->rgsabound->cElements) { SafeArrayAccessData( pEventNames, (void**)&ppvData); for (LONG i = 0; (ULONG)i < pEventTypes->rgsabound->cElements; i++) { int ClassEventType = 0; hrSafe = SafeArrayGetElement(pEventTypes, &i, &ClassEventType); CMofParseRes* pMofParseRes2 = (CMofParseRes*)malloc(sizeof(CMofParseRes)); if (pMofParseRes2) { ZeroMemory(pMofParseRes2,sizeof(CMofParseRes)); InitializeListHead(&pMofParseRes2->m_MofPropertyList); pMofParseRes2->m_MofHeader.MofClassName = SysAllocString(szClassName); memcpy( &pMofParseRes2->m_MofHeader.MofGuid, &Guid, sizeof(GUID)); pMofParseRes2->m_MofHeader.MofType = ClassEventType; pMofParseRes2->m_MofHeader.MofLevel = Level; pMofParseRes2->m_MofHeader.MofVsersion = Version; pMofParseRes2->m_MofHeader.MofTypeName = SysAllocString(ppvData[i]); InsertTailList(&pList,&pMofParseRes2->m_Entry); if (ClassEventType == EventType) { pMofParseRes = pMofParseRes2; } } } } } VariantClear(&vargTypeName); } else { VARIANT vargTypeName; VariantInit(&vargTypeName); if ( pQualifiers->Get( BSTR(_T("EventTypeName")), 0, &vargTypeName, 0) == S_OK ) { VariantChangeType(&varEventType, &varEventType, 0, VT_I2); USHORT vType = varEventType.iVal; CMofParseRes* pMofParseRes2 = (CMofParseRes*)malloc(sizeof(CMofParseRes)); if (pMofParseRes2) { ZeroMemory(pMofParseRes2,sizeof(CMofParseRes)); InitializeListHead(&pMofParseRes2->m_MofPropertyList); pMofParseRes2->m_MofHeader.MofClassName = SysAllocString(szClassName); memcpy( &pMofParseRes2->m_MofHeader.MofGuid, &Guid, sizeof(GUID)); pMofParseRes2->m_MofHeader.MofType = vType; pMofParseRes2->m_MofHeader.MofLevel = Level; pMofParseRes2->m_MofHeader.MofVsersion = Version; pMofParseRes2->m_MofHeader.MofTypeName = SysAllocString(vargTypeName.bstrVal); InsertTailList(&pList,&pMofParseRes2->m_Entry); if (vType == EventType) { //FoundEventClass = TRUE; pMofParseRes = pMofParseRes2; } } } VariantClear(&vargTypeName); } VariantClear(&varEventType); SAFEARRAY* pNames = NULL; VARIANT QualifierVal; VariantInit(&QualifierVal); QualifierVal.vt = VT_I4; QualifierVal.lVal = 1; LONG rgIndices = 0; while(TRUE) { hr = pClass->GetNames( (BSTR)_T("WmiDataId"), WBEM_FLAG_ONLY_IF_IDENTICAL, &QualifierVal, &pNames); if (hr != S_OK) { break; } if (!pNames->rgsabound->cElements) { break; } rgIndices = 0; do { BSTR pvElement = NULL; CIMTYPE QualifierType = 0; if ( SafeArrayGetElement(pNames, &rgIndices, &pvElement) || pClass->Get(pvElement, 0, 0, &QualifierType, 0)) { break; } if ( pQualifiers ) { pQualifiers->Release(); pQualifiers = 0; } if(pClass->GetPropertyQualifierSet(pvElement,&pQualifiers)) { break; } LONG dwLen = GetArrayValue(QualifierType,pQualifiers); LONG ArraySize = QualifierType & VT_ARRAY ? GetArraySize(pQualifiers) : 1; AddProperityList( &pList, pvElement, dwLen, ArraySize); rgIndices++; } while(rgIndices < pNames->rgsabound->cElements); QualifierVal.lVal++; SafeArrayDestroy(pNames); pNames = 0; } pClass->Release(); pClass = NULL; AddGlobalEvent(&pList); } cleanup: if (pClass) { pClass->Release(); pClass = NULL; } if (pClasses) { pClasses->Release(); pClasses = NULL; } if (pQualifiers) { pQualifiers->Release(); pQualifiers = NULL; } AddGlobalEvent(&pList); VariantClear(&varClassName); VariantClear(&varEventType); VariantClear(&varDisplayName); return pMofParseRes; } BOOL CMofDataParser::GetPropertyList( IWbemClassObject* pClass, PROPERTY_LIST** ppProperties, DWORD* pPropertyCount, LONG* PropertyIndex) { HRESULT hr = S_OK; SAFEARRAY* pNames = NULL; LONG j = 0; VARIANT var; // Retrieve the property names. hr = pClass->GetNames( NULL, WBEM_FLAG_LOCAL_ONLY, NULL, &pNames); if (pNames) { *pPropertyCount = pNames->rgsabound->cElements; *ppProperties = new PROPERTY_LIST[*pPropertyCount]; if ( NULL == *ppProperties) { hr = E_OUTOFMEMORY; goto cleanup; } ZeroMemory( *ppProperties, sizeof(PROPERTY_LIST) * (*pPropertyCount) ); for (LONG i = 0; (ULONG)i < *pPropertyCount; i++) { PROPERTY_LIST* pCurProperList = &(*ppProperties)[i]; __try { hr = SafeArrayGetElement( pNames, &i, &(pCurProperList->Name)); if (FAILED(hr)) { goto cleanup; } //Save the qualifiers. Used latter to help determine how to read the event data. hr = pClass->GetPropertyQualifierSet( pCurProperList->Name, &(pCurProperList->pQualifiers)); if (FAILED(hr)) { goto cleanup; } hr = pCurProperList->pQualifiers->Get( L"WmiDataId", 0, &var, NULL); if (SUCCEEDED(hr)) { j = var.intVal - 1; VariantClear(&var); *(PropertyIndex + j ) = i; } else { goto cleanup; } hr = pClass->Get( pCurProperList->Name, 0, NULL, &(pCurProperList->CimType), NULL); if (FAILED(hr)) { goto cleanup; } } __except(EXCEPTION_EXECUTE_HANDLER) { } } } cleanup: if (pNames) { SafeArrayDestroy(pNames); } if (FAILED(hr)) { if (*ppProperties) { FreePropertyList( *ppProperties, *pPropertyCount); } return FALSE; } return TRUE; } void CMofDataParser::FreePropertyList( PROPERTY_LIST* pProperties, DWORD Count) { if(pProperties) { for (DWORD i=0; i < Count; i++) { SysFreeString((pProperties+i)->Name); if ((pProperties+i)->pQualifiers) { (pProperties+i)->pQualifiers->Release(); (pProperties+i)->pQualifiers = NULL; } } delete[] pProperties; pProperties = NULL; } } void CMofDataParser::GetPropertyName( PROPERTY_LIST* pProperty, TCHAR* PropertyName) { HRESULT hr; VARIANT varDisplayName; VariantInit(&varDisplayName); __try { hr = pProperty->pQualifiers->Get( L"DisplayName", 0, &varDisplayName, NULL); } __except (EXCEPTION_EXECUTE_HANDLER) { hr = -1; } if (SUCCEEDED(hr)) { PropertyName = SysAllocString(varDisplayName.bstrVal); } else { PropertyName = SysAllocString(pProperty->Name); } VariantClear(&varDisplayName); } PBYTE CMofDataParser::GetPropertyValue( PROPERTY_LIST* pProperty, MOF_ITEM& MofItem, PBYTE pEventData, USHORT RemainingBytes) { HRESULT hr; VARIANT varQualifier; ULONG ArraySize = 1; BOOL PrintAsChar = FALSE; BOOL PrintAsHex = FALSE; BOOL PrintAsIPAddress = FALSE; BOOL PrintAsPort = FALSE; BOOL IsWideString = FALSE; BOOL IsNullTerminated = FALSE; USHORT StringLength = 0; MofItem.ArraySize = 0; MofItem.cValues = 0; MofItem.liValue.QuadPart = 0; if (SUCCEEDED(hr = pProperty->pQualifiers->Get( L"Pointer", 0, NULL, NULL)) || SUCCEEDED(hr = pProperty->pQualifiers->Get( L"PointerType", 0, NULL, NULL))) { if (m_PointerSize == 4) { ULONG temp = 0; CopyMemory( &temp, pEventData, sizeof(ULONG)); MofItem.Types = OTHER_VALUE; MofItem.liValue.LowPart = temp; } else { ULONGLONG temp = 0; CopyMemory( &temp, pEventData, sizeof(ULONGLONG)); MofItem.Types = OTHER_VALUE; MofItem.liValue.QuadPart = temp; } pEventData += m_PointerSize; return pEventData; } else { if (pProperty->CimType & CIM_FLAG_ARRAY) { hr = pProperty->pQualifiers->Get( L"MAX", 0, &varQualifier, NULL); if (SUCCEEDED(hr)) { ArraySize = varQualifier.intVal; VariantClear(&varQualifier); } else { //wprintf(L"Failed to retrieve the MAX qualifier. Terminating.\n"); return NULL; } } // The CimType is the data type of the property. switch(pProperty->CimType & (~CIM_FLAG_ARRAY)) { case CIM_SINT32: { LONG temp = 0; MofItem.u32ArrayValue = new uint32[ArraySize]; if ( MofItem.u32ArrayValue) { for ( ULONG i = 0 ; i < ArraySize ; i++) { CopyMemory( &temp, pEventData, sizeof(LONG)); MofItem.u32ArrayValue[i] = temp; pEventData += sizeof(LONG); } MofItem.Types = UINT32_ARRAY_VALUE; } else { return NULL; } return pEventData; } case CIM_UINT32: { ULONG temp = 0; hr = pProperty->pQualifiers->Get( L"Extension", 0, &varQualifier, NULL); if (SUCCEEDED(hr)) { if (_wcsicmp(L"IPAddr", varQualifier.bstrVal) == 0) { PrintAsIPAddress = TRUE; } VariantClear(&varQualifier); } else { hr = pProperty->pQualifiers->Get( L"Format", 0, NULL, NULL); if (SUCCEEDED(hr)) { PrintAsHex = TRUE; } } MofItem.u32ArrayValue = new uint32[ArraySize]; if ( MofItem.u32ArrayValue) { for (ULONG i = 0; i < ArraySize; i++) { CopyMemory(&temp, pEventData, sizeof(ULONG)); if (PrintAsIPAddress) { // wprintf(L"%03d.%03d.%03d.%03d\n", (temp >> 0) & 0xff, // (temp >> 8) & 0xff, // (temp >> 16) & 0xff, // (temp >> 24) & 0xff); MofItem.u32ArrayValue[i] = temp; } else if (PrintAsHex) { //wprintf(L"0x%x\n", temp); MofItem.u32ArrayValue[i] = temp; } else { //wprintf(L"%lu\n", temp); MofItem.u32ArrayValue[i] = temp; } pEventData += sizeof(ULONG); } MofItem.Types = UINT32_ARRAY_VALUE; } else { return NULL; } return pEventData; } case CIM_SINT64: { LONGLONG temp = 0; for (ULONG i=0; i < ArraySize; i++) { CopyMemory( &temp, pEventData, sizeof(LONGLONG)); //wprintf(L"%I64d\n", temp); MofItem.liValue.QuadPart = temp; MofItem.Types = OTHER_VALUE; pEventData += sizeof(LONGLONG); } return pEventData; } case CIM_UINT64: { ULONGLONG temp = 0; for (ULONG i=0; i < ArraySize; i++) { CopyMemory(&temp, pEventData, sizeof(ULONGLONG)); //wprintf(L"%I64u\n", temp); MofItem.liValue.QuadPart = temp; MofItem.Types = OTHER_VALUE; pEventData += sizeof(ULONGLONG); } return pEventData; } case CIM_STRING: { USHORT temp = 0; if( _wcsicmp( _T("ApplicationId"), MofItem.Name)) { hr = pProperty->pQualifiers->Get( L"Format", 0, NULL, NULL); if (SUCCEEDED(hr)) { IsWideString = TRUE; } hr = pProperty->pQualifiers->Get( L"StringTermination", 0, &varQualifier, NULL); if (FAILED(hr) || (_wcsicmp( varQualifier.bstrVal, L"NullTerminated") == 0)) { IsNullTerminated = TRUE; } else if (_wcsicmp( varQualifier.bstrVal, L"Counted") == 0) { // First two bytes of the string contain its length. CopyMemory( &StringLength, pEventData, sizeof(USHORT)); pEventData += sizeof(USHORT); } else if (_wcsicmp( varQualifier.bstrVal, L"ReverseCounted") == 0) { CopyMemory( &temp, pEventData, sizeof(USHORT)); StringLength = MAKEWORD( HIBYTE(temp), LOBYTE(temp)); pEventData += sizeof(USHORT); } else if (_wcsicmp( varQualifier.bstrVal, L"NotCounted") == 0) { StringLength = RemainingBytes; } if ( ArraySize) { MofItem.mofcArray = new MOF_CHAR_ARRAY[ArraySize]; if ( MofItem.mofcArray) { MofItem.Types = CHAR_ARRAY_VALUE; ZeroMemory( MofItem.mofcArray, sizeof(MOF_CHAR_ARRAY)*ArraySize); MofItem.ArraySize = ArraySize; } else { return NULL; } } VariantClear(&varQualifier); for (ULONG i = 0; i < ArraySize; i++) { if (IsWideString) { if (IsNullTerminated) { StringLength = (USHORT)(wcslen((WCHAR*)pEventData)); StringLength += sizeof(WCHAR); if ( StringLength && MofItem.mofcArray ) { MofItem.mofcArray[i].Name[0] = i; MofItem.mofcArray[i].wValue = new WCHAR[StringLength]; if (MofItem.mofcArray[i].wValue) { StringCchCopy( MofItem.mofcArray[i].wValue, StringLength, (STRSAFE_LPCWSTR)pEventData); } } } else { LONG StringSize = (StringLength) * sizeof(WCHAR); //WCHAR* pwsz = (WCHAR*)malloc(StringSize + sizeof(WCHAR)); // +2 for NULL if (MofItem.mofcArray) { MofItem.mofcArray[i].Name[0] = i; MofItem.mofcArray[i].wValue = new WCHAR[StringLength+1]; if (MofItem.mofcArray[i].wValue) { CopyMemory( MofItem.mofcArray[i].wValue, (WCHAR*)pEventData, StringSize); *(MofItem.mofcArray[i].wValue+StringSize) = '\0'; } } } StringLength *= sizeof(WCHAR); } else // It is an ANSI string { if (IsNullTerminated) { StringLength = (USHORT)strlen((char*)pEventData) + 1; //printf("%s\n", (char*)pEventData); if ( StringLength && MofItem.mofcArray ) { MofItem.mofcArray[i].Name[0] = i; MofItem.mofcArray[i].cValue = new char[StringLength]; if (MofItem.mofcArray[i].cValue) { StringCchCopyA( MofItem.mofcArray[i].cValue, StringLength, (STRSAFE_LPCSTR)pEventData); } } } else { //char* psz = (char*)malloc(StringLength+1); // +1 for NULL if (MofItem.mofcArray) { MofItem.mofcArray[i].Name[0] = i; MofItem.mofcArray[i].cValue = new char[StringLength+1]; if (MofItem.mofcArray[i].cValue) { CopyMemory( MofItem.mofcArray[i].cValue, (char*)pEventData, StringLength); *(MofItem.mofcArray[i].cValue + StringLength) = '\0'; } } } } pEventData += StringLength; StringLength = 0; } } else { MofItem.Types = OTHER_VALUE; MofItem.liValue.QuadPart = 0; CopyMemory( &MofItem.liValue.LowPart, pEventData, 4); (UCHAR*)pEventData += 4; } return pEventData; } case CIM_BOOLEAN: { BOOL temp = FALSE; for (ULONG i = 0; i < ArraySize; i++) { CopyMemory(&temp, pEventData, sizeof(BOOL)); wprintf(L"%s\n", (temp) ? L"TRUE" : L"FALSE"); pEventData += sizeof(BOOL); } return pEventData; } case CIM_SINT8: case CIM_UINT8: { hr = pProperty->pQualifiers->Get( L"Extension", 0, &varQualifier, NULL); if (SUCCEEDED(hr)) { if (_wcsicmp( L"Guid", varQualifier.bstrVal) == 0) { WCHAR szGuid[50] = {0}; GUID Guid; CopyMemory( &Guid, (GUID*)pEventData, sizeof(GUID)); StringFromGUID2( Guid, szGuid, sizeof(szGuid)-1); MofItem.Types = TCHAR_VALUE; MofItem.cValues = new TCHAR[50]; if (MofItem.cValues) { StringCchCopy( MofItem.cValues, 50, szGuid ); } } VariantClear(&varQualifier); pEventData += sizeof(GUID); } else { hr = pProperty->pQualifiers->Get( L"Format", 0, NULL, NULL); if (SUCCEEDED(hr)) { PrintAsChar = TRUE; // ANSI character } for (ULONG i = 0; i < ArraySize; i++) { if (PrintAsChar) wprintf(L"%c", *((char*)pEventData)); else wprintf(L"%hd", *((BYTE*)pEventData)); pEventData += sizeof(UINT8); } } wprintf(L"\n"); return pEventData; } case CIM_CHAR16: { WCHAR temp; for (ULONG i = 0; i < ArraySize; i++) { CopyMemory(&temp, pEventData, sizeof(WCHAR)); wprintf(L"%c", temp); pEventData += sizeof(WCHAR); } wprintf(L"\n"); return pEventData; } case CIM_SINT16: { SHORT temp = 0; for (ULONG i = 0; i < ArraySize; i++) { CopyMemory(&temp, pEventData, sizeof(SHORT)); wprintf(L"%hd\n", temp); pEventData += sizeof(SHORT); } return pEventData; } case CIM_UINT16: { USHORT temp = 0; // If the data is a port number, call the ntohs Windows Socket 2 function // to convert the data from TCP/IP network byte order to host byte order. // This is here to support legacy event classes; the Port extension // should only be used on properties whose CIM type is object. hr = pProperty->pQualifiers->Get( L"Extension", 0, &varQualifier, NULL); if (SUCCEEDED(hr)) { if (_wcsicmp( L"Port", varQualifier.bstrVal) == 0) { PrintAsPort = TRUE; } VariantClear(&varQualifier); } if (ArraySize) { MofItem.u32ArrayValue = new uint32[ArraySize]; if (MofItem.u32ArrayValue) { MofItem.Types = UINT32_ARRAY_VALUE; ZeroMemory( MofItem.u32ArrayValue, sizeof(uint32)*ArraySize ); } } for (ULONG i = 0; i < ArraySize; i++) { CopyMemory( &temp, pEventData, sizeof(USHORT)); if (MofItem.u32ArrayValue) { if (PrintAsPort) { MofItem.u32ArrayValue[i] = ntohs(temp); } else { MofItem.u32ArrayValue[i] = temp; } } pEventData += sizeof(USHORT); } return pEventData; } case CIM_OBJECT: { // An object data type has to include the Extension qualifier. hr = pProperty->pQualifiers->Get( L"Extension", 0, &varQualifier, NULL); if (SUCCEEDED(hr)) { if (_wcsicmp( L"SizeT", varQualifier.bstrVal) == 0) { VariantClear(&varQualifier); // You do not need to know the data type of the property, you just // retrieve either 4 bytes or 8 bytes depending on the pointer's size. for (ULONG i = 0; i < ArraySize; i++) { if (m_PointerSize == 4) { ULONG temp = 0; CopyMemory( &temp, pEventData, sizeof(ULONG)); wprintf(L"0x%x\n", temp); } else { ULONGLONG temp = 0; CopyMemory(&temp, pEventData, sizeof(ULONGLONG)); wprintf(L"0x%x\n", temp); } pEventData += m_PointerSize; } return pEventData; } if (_wcsicmp( L"Port", varQualifier.bstrVal) == 0) { USHORT temp = 0; VariantClear(&varQualifier); for (ULONG i = 0; i < ArraySize; i++) { CopyMemory( &temp, pEventData, sizeof(USHORT)); wprintf(L"%hu\n", ntohs(temp)); pEventData += sizeof(USHORT); } return pEventData; } else if (_wcsicmp(L"IPAddr", varQualifier.bstrVal) == 0 || _wcsicmp(L"IPAddrV4", varQualifier.bstrVal) == 0) { ULONG temp = 0; VariantClear(&varQualifier); for (ULONG i = 0; i < ArraySize; i++) { CopyMemory(&temp, pEventData, sizeof(ULONG)); wprintf(L"%d.%d.%d.%d\n", (temp >> 0) & 0xff, (temp >> 8) & 0xff, (temp >> 16) & 0xff, (temp >> 24) & 0xff); pEventData += sizeof(ULONG); } return pEventData; } else if (_wcsicmp( L"IPAddrV6", varQualifier.bstrVal) == 0) { typedef LPTSTR (WINAPI *PIPV6ADDRTOSTRING)( const IN6_ADDR *Addr, LPTSTR S ); WCHAR IPv6AddressAsString[46] = {0}; IN6_ADDR IPv6Address; PIPV6ADDRTOSTRING fnRtlIpv6AddressToString; VariantClear(&varQualifier); fnRtlIpv6AddressToString = (PIPV6ADDRTOSTRING) GetProcAddress( GetModuleHandle(L"ntdll"), "RtlIpv6AddressToStringW"); if (NULL == fnRtlIpv6AddressToString) { wprintf(L"GetProcAddress failed with %lu.\n", GetLastError()); return NULL; } for (ULONG i = 0; i < ArraySize; i++) { CopyMemory( &IPv6Address, pEventData, sizeof(IN6_ADDR)); fnRtlIpv6AddressToString( &IPv6Address, IPv6AddressAsString); wprintf(L"%s\n", IPv6AddressAsString); pEventData += sizeof(IN6_ADDR); } return pEventData; } else if (_wcsicmp(L"Guid", varQualifier.bstrVal) == 0) { WCHAR szGuid[50] = {0}; GUID Guid; VariantClear(&varQualifier); for (ULONG i = 0; i < ArraySize; i++) { CopyMemory(&Guid, (GUID*)pEventData, sizeof(GUID)); StringFromGUID2(Guid, szGuid, sizeof(szGuid)-1); wprintf(L"%s\n", szGuid); pEventData += sizeof(GUID); } return pEventData; } else if (_wcsicmp(L"Sid", varQualifier.bstrVal) == 0) { // Get the user's security identifier and print the // user's name and domain. SID* psid; DWORD cchUserSize = 0; DWORD cchDomainSize = 0; WCHAR* pUser = NULL; WCHAR* pDomain = NULL; SID_NAME_USE eNameUse; DWORD status = 0; ULONG temp = 0; USHORT CopyLength = 0; BYTE buffer[SECURITY_MAX_SID_SIZE]; VariantClear(&varQualifier); if ( ArraySize == 1) { MofItem.mofcArray = new MOF_CHAR_ARRAY[2]; if (MofItem.mofcArray) { MofItem.Types = CHAR_ARRAY_VALUE; ZeroMemory( MofItem.mofcArray, sizeof(MOF_CHAR_ARRAY)*2); MofItem.ArraySize = 2; } } for (ULONG i = 0; i < ArraySize; i++) { CopyMemory( &temp, pEventData, sizeof(ULONG)); if (temp > 0) { USHORT BytesToSid = m_PointerSize * 2; pEventData += BytesToSid; if (RemainingBytes - BytesToSid > SECURITY_MAX_SID_SIZE) { CopyLength = SECURITY_MAX_SID_SIZE; } else { CopyLength = RemainingBytes - BytesToSid; } CopyMemory( &buffer, pEventData, CopyLength); psid = (SID*)&buffer; LookupAccountSid( NULL, psid, pUser, &cchUserSize, pDomain, &cchDomainSize, &eNameUse); status = GetLastError(); if (ERROR_INSUFFICIENT_BUFFER == status) { pUser = (WCHAR*)malloc(cchUserSize * sizeof(WCHAR)); pDomain = (WCHAR*)malloc(cchDomainSize * sizeof(WCHAR)); if (pUser && pDomain) { if (LookupAccountSid( NULL, psid, pUser, &cchUserSize, pDomain, &cchDomainSize, &eNameUse)) { if ( i == 0) { if ( MofItem.mofcArray ) { MofItem.mofcArray[0].wValue = new WCHAR[cchDomainSize]; if (MofItem.mofcArray[0].wValue) { StringCchCopy( MofItem.mofcArray[0].Name, 50, _T("Domain") ); StringCchCopy( MofItem.mofcArray[0].wValue, cchDomainSize, pDomain ); } MofItem.mofcArray[1].wValue = new WCHAR[cchUserSize]; if (MofItem.mofcArray[1].wValue) { StringCchCopy( MofItem.mofcArray[1].Name, 50, _T("User") ); StringCchCopy( MofItem.mofcArray[1].wValue, cchUserSize, pUser ); } } } } else { wprintf(L"Second LookupAccountSid failed with, %d\n", GetLastError()); } } else { wprintf(L"Allocation error.\n"); } if (pUser) { free(pUser); pUser = NULL; } if (pDomain) { free(pDomain); pDomain = NULL; } cchUserSize = 0; cchDomainSize = 0; } else if (ERROR_NONE_MAPPED == status) { wprintf(L"Unable to locate account for the specified SID\n"); } else { wprintf(L"First LookupAccountSid failed with, %d\n", status); } pEventData += SeLengthSid(psid); } else // There is no SID { pEventData += sizeof(ULONG); } } return pEventData; } else { wprintf(L"Extension, %s, not supported.\n", varQualifier.bstrVal); VariantClear(&varQualifier); return NULL; } } else { wprintf(L"Object data type is missing Extension qualifier.\n"); return NULL; } } default: { wprintf(L"Unknown CIM type\n"); return NULL; } } // switch } } LONG CMofDataParser::GetArraySize( IWbemQualifierSet* pQualifierSet) { LONG ArraySize = 1; VARIANT varQualifier; HRESULT hr; if ( pQualifierSet ) { BSTR bstrMax = SysAllocString(L"MAX"); VariantInit(&varQualifier); hr = pQualifierSet->Get(bstrMax, 0, &varQualifier, 0); SysFreeString(bstrMax); if ( !hr && varQualifier.vt == 3 ) ArraySize = varQualifier.lVal; VariantClear(&varQualifier); } return ArraySize; } LONG CMofDataParser::GetArrayValue( CIMTYPE CimType, IWbemQualifierSet * pQualifierSet) { LONG RetValue = 29; BSTR bstrQualifier; VARIANT varQualifier; HRESULT hr; BOOL bPointer; OLECHAR szFormat[11]; OLECHAR szStringTermination[31]; OLECHAR szExtension[31]; bPointer = 0; szFormat[0] = 0; szStringTermination[0] = 0; szExtension[0] = 0; if (pQualifierSet) { bstrQualifier = SysAllocString(L"Format"); VariantInit(&varQualifier); hr = pQualifierSet->Get(bstrQualifier, 0, &varQualifier, 0); SysFreeString(bstrQualifier); if ( !hr && varQualifier.lVal ) StringCchCopy(szFormat, 10, varQualifier.bstrVal); bstrQualifier = SysAllocString(L"StringTermination"); VariantClear(&varQualifier); hr = pQualifierSet->Get(bstrQualifier, 0, &varQualifier, 0); SysFreeString(bstrQualifier); if ( !hr && varQualifier.lVal ) StringCchCopy(szStringTermination, 30, varQualifier.bstrVal); bstrQualifier = SysAllocString(L"Pointer"); VariantClear(&varQualifier); hr = pQualifierSet->Get(bstrQualifier, 0, &varQualifier, 0); SysFreeString(bstrQualifier); if ( hr == S_OK) { bPointer = 1; } bstrQualifier = SysAllocString(L"Extension"); VariantClear(&varQualifier); hr = pQualifierSet->Get(bstrQualifier, 0, &varQualifier, 0); SysFreeString(bstrQualifier); if ( !hr && varQualifier.lVal ) StringCchCopy(szExtension, 30, varQualifier.bstrVal); VariantClear(&varQualifier); switch ( CimType & (~CIM_FLAG_ARRAY) ) { case CIM_SINT16: RetValue = 4; break; case CIM_SINT32: RetValue = 6; break; case CIM_REAL32: RetValue = 11; break; case CIM_REAL64: RetValue = 12; break; case CIM_STRING: { if ( _wcsicmp(szStringTermination, L"NullTerminated") ) { if ( _wcsicmp(szStringTermination, L"Counted") ) { if ( _wcsicmp(szStringTermination, L"ReverseCounted") ) RetValue = _wcsicmp(szStringTermination, L"NotCounted") != 0 ? 13 : 23; else RetValue = 18 - (_wcsicmp(szFormat, L"w") != 0); } else { RetValue = 16 - (_wcsicmp(szFormat, L"w") != 0); } } else { RetValue = 14 - (_wcsicmp(szFormat, L"w") != 0); } } break; case CIM_BOOLEAN: RetValue = 26; break; case CIM_OBJECT: if ( !_wcsicmp(szExtension, L"Port") ) { RetValue = 21; } else { if ( !_wcsicmp(szExtension, L"IPAddr") ) { RetValue = 20; } else if ( _wcsicmp(szExtension, L"Sid") ) { if ( _wcsicmp(szExtension, L"Guid") ) { if ( !_wcsicmp(szExtension, L"SizeT") ) { RetValue = 6; } else { if ( _wcsicmp(szExtension, L"IPAddrV6") ) { if ( _wcsicmp(szExtension, L"IPAddrV4") ) { if ( !_wcsicmp(szExtension, L"WmiTime") ) RetValue = 28; } else { RetValue = 20; } } else { RetValue = 27; } } } else { RetValue = 25; } } else { RetValue = 19; } } break; case CIM_SINT8: RetValue = 3; if ( !_wcsicmp(szFormat, L"c") ) RetValue = 0; break; case CIM_UINT8: RetValue = 2; break; case CIM_UINT16: RetValue = 5; break; case CIM_UINT32: RetValue = 7; break; case CIM_SINT64: RetValue = 9; break; case CIM_UINT64: RetValue = 10; break; case CIM_CHAR16: RetValue = 1; break; } if (bPointer) { RetValue = 24; } } return RetValue; } void CMofDataParser::AddProperityList( LIST_ENTRY* plist, BSTR pvData, LONG ValueLen, LONG ArraySize) { LIST_ENTRY* pEntry = plist->Flink; while(pEntry != plist) { CMofParseRes* pRes = CONTAINING_RECORD( pEntry, CMofParseRes, m_Entry); if (pRes) { MOF_PROPERTY* pProperty = (MOF_PROPERTY*) malloc(sizeof(MOF_PROPERTY)); if (pProperty) { __try { ZeroMemory(pProperty,sizeof(MOF_PROPERTY)); pProperty->Entry.Flink = pProperty->Entry.Blink = 0; int nLen = 0; if (pvData && (nLen = lstrlen(pvData))) { pProperty->ArraySize = ArraySize; pProperty->Types = ValueLen; pProperty->Name = (BSTR)malloc((nLen+1)* sizeof(OLECHAR)); if (pProperty->Name) { __try { StringCchCopy( pProperty->Name, nLen + 1, pvData); InsertTailList( &pRes->m_MofPropertyList, &pProperty->Entry); } __except(EXCEPTION_EXECUTE_HANDLER) { if (pProperty->Name) { free(pProperty->Name); pProperty->Name = NULL; } } } else { free(pProperty); pProperty = NULL; } } } __except(EXCEPTION_EXECUTE_HANDLER) { if (pProperty) { free(pProperty); pProperty = NULL; } } } } __try { pEntry = pEntry->Flink; } __except(EXCEPTION_EXECUTE_HANDLER) { break; } } } void CMofDataParser::AddGlobalEvent( LIST_ENTRY* plist ) { while(!IsListEmpty(plist)) { LIST_ENTRY* pEntry = plist->Flink; __try { CMofParseRes* pRes = CONTAINING_RECORD( pEntry, CMofParseRes, m_Entry); if (pRes) { RemoveEntryList(&pRes->m_Entry); InsertTailList(&m_ModDataList,&pRes->m_Entry); } } __except(EXCEPTION_EXECUTE_HANDLER) { break; } } InitializeListHead(plist); } ================================================ FILE: Sysmon/CMofDataParser.h ================================================ #ifndef _CMofDataParser_h #define _CMofDataParser_h #include "Sysmon.h" #define MAX_CHAR_ARRAY_SIZE 20 #define TCHAR_VALUE 0x1 #define UINT32_ARRAY_VALUE 0x2 #define OTHER_VALUE 0x4 #define CHAR_ARRAY_VALUE 0x8 #include #include #include #include typedef unsigned int uint32; typedef unsigned long long uint64; extern "C" { typedef HRESULT (WINAPI * pSafeArrayDestroy)(SAFEARRAY *); typedef HRESULT (WINAPI * pSafeArrayGetElement)(SAFEARRAY * , LONG *, void *); }; typedef struct _MOF_DATA_HEADER { int MofCount; SYSTEMTIME MofLocal; BSTR MofClassName; BSTR MofTypeName; USHORT MofType; USHORT MofLevel; USHORT MofVsersion; GUID MofGuid; }MOF_DATA_HEADER; typedef struct _MOF_CHAR_ARRAY { TCHAR Name[20]; union { char* cValue; WCHAR* wValue; }; }MOF_CHAR_ARRAY; typedef struct _MOF_ITEM { TCHAR Name[50]; ULONG Types; UINT32 ArraySize; union { TCHAR* cValues; LARGE_INTEGER liValue; UINT32* u32ArrayValue; MOF_CHAR_ARRAY* mofcArray; }; }MOF_ITEM,*PMOF_ITEM; typedef struct _MOF_PROPERTY { LIST_ENTRY Entry; BSTR Name; ULONG Types; UINT32 ArraySize; }MOF_PROPERTY; class CMofParseRes { friend class CMofDataParser; public: CMofParseRes() { ZeroMemory( this, sizeof(*this)); InitializeListHead( &m_MofPropertyList ); } ~CMofParseRes() { } UINT32 GetCount() { return m_MofHeader.MofCount; } SYSTEMTIME GetTimeStmp() { return m_MofHeader.MofLocal; } public: LIST_ENTRY m_Entry; private: MOF_DATA_HEADER m_MofHeader; LIST_ENTRY m_MofPropertyList; }; typedef struct _propertyList { BSTR Name; LONG CimType; IWbemQualifierSet* pQualifiers; } PROPERTY_LIST; class CMofData { public: CMofData(void) { m_Mof = NULL; memset( &m_MofHead, 0, sizeof(MOF_DATA_HEADER)); } CMofData(const CMofData& Mof) { m_Mof = Mof.m_Mof; } CMofData(const PMOF_ITEM& Mof) { m_Mof = Mof; } ~CMofData(void) { } void operator =(const PMOF_ITEM Mof) { m_Mof = Mof; } BOOL operator ==(const TCHAR* Name ) { if ( m_Mof ) { if (sizeof(TCHAR) >= 2 ) { if ( !wcsicmp(Name,m_Mof->Name)) { return TRUE; } } else { if (!stricmp( (char*)Name, (char*)m_Mof->Name)) { return TRUE; } } } return FALSE; } UINT32 getDataInt32( UINT32 DataType ,int Index = 0) { if ( m_Mof ) { if(m_Mof->Types == DataType ) { if (DataType == UINT32_ARRAY_VALUE) { if (m_Mof->u32ArrayValue) { return m_Mof->u32ArrayValue[Index]; } } else if ( DataType == CHAR_ARRAY_VALUE ) { if ( m_Mof->mofcArray ) { return (UINT32)&m_Mof->mofcArray[Index]; } } } } return 0; } UINT64 getDataInt64( UINT32 DataType ,int Index = 0 ) { if ( m_Mof ) { if(m_Mof->Types == DataType ) { if (DataType == OTHER_VALUE) { return m_Mof->liValue.QuadPart; } } } return 0; } TCHAR* getWideString( UINT32 DataType ,int Index = 0 ) { if ( m_Mof ) { if(m_Mof->Types == DataType ) { if (DataType == CHAR_ARRAY_VALUE ) { if (m_Mof->mofcArray) { return m_Mof->mofcArray[Index].wValue; } } else if ( DataType == TCHAR_VALUE ) { if ( m_Mof->cValues ) { return (TCHAR*)m_Mof->cValues; } } } } return NULL; } char* getAnsiString( UINT32 DataType ,int Index = 0 ) { if ( m_Mof ) { if(m_Mof->Types == DataType ) { if (DataType == CHAR_ARRAY_VALUE ) { if (m_Mof->mofcArray) { return m_Mof->mofcArray[Index].cValue; } } else if ( DataType == TCHAR_VALUE ) { if ( m_Mof->cValues ) { return (char*)m_Mof->cValues; } } } } return NULL; } UINT32 GetProcessId() { return getDataInt32( UINT32_ARRAY_VALUE ); } UINT64 GetUniqueProcessKey() { return getDataInt64( OTHER_VALUE ); } char* GetProcessImageFileName() { char* ImageFileName = NULL; if (! (ImageFileName = getAnsiString( TCHAR_VALUE , 0 )) ) { ImageFileName = getAnsiString(CHAR_ARRAY_VALUE,0); } return ImageFileName; } /************************************************************************/ /* FileObject */ /************************************************************************/ UINT64 GetFileObject() { return getDataInt64(OTHER_VALUE,0); } TCHAR* GetFileOpenPath() { TCHAR* OpenPath = NULL; if ( !(OpenPath = getWideString( TCHAR_VALUE, 0))) { OpenPath = getWideString( CHAR_ARRAY_VALUE, 0); } return OpenPath; } private: MOF_DATA_HEADER m_MofHead; PMOF_ITEM m_Mof; LIST_ENTRY m_Entry; }; class CMofDataParser { public: CMofDataParser(void); virtual ~CMofDataParser(void); private: HRESULT Connect( BSTR bstrNamespace ); public: void SetPointSize(ULONG PointSize ) { m_PointerSize = 8; } BOOL Parse( PEVENT_TRACE pEvent, CMofParseRes& Result ); private: IWbemServices* m_pServices; ULONG m_PointerSize; LIST_ENTRY m_ModDataList; protected: void GetPropertyName( PROPERTY_LIST* pProperty, TCHAR* PropertyName ); PBYTE GetPropertyValue( PROPERTY_LIST* pProperty, MOF_ITEM& MofItem, PBYTE pEventData, USHORT RemainingBytes); IWbemClassObject* GetEventCategoryClass( BSTR bstrClassGuid, int Version); CMofParseRes* GetEventClassPropertyList( IWbemClassObject* pEventCategoryClass, GUID& Guid, USHORT Version, USHORT Level, USHORT EventType); void FreePropertyList( PROPERTY_LIST* pProperties, DWORD Count); BOOL GetPropertyList( IWbemClassObject* pClass, PROPERTY_LIST** ppProperties, DWORD* pPropertyCount, LONG* PropertyIndex); LONG GetArraySize( IWbemQualifierSet* pQualifierSet); LONG GetArrayValue( CIMTYPE CimType, IWbemQualifierSet * pQualifierSet); void AddProperityList( LIST_ENTRY* Entry, BSTR pvData, LONG ValueLen, LONG ArraySize); void AddGlobalEvent( LIST_ENTRY* Entry); public: CMofDataParser* Instance(); }; class FileCreateNameX86 { public: FileCreateNameX86(void) { } ~FileCreateNameX86() { } UINT32 FileObject; TCHAR FileName[1]; }; class CPropertyRes; class CPropertyRes { friend class CPropertyData; public: CPropertyRes(void) { ZeroMemory(this,sizeof(*this)); } CPropertyRes(const CPropertyRes& Res) { ZeroMemory(this,sizeof(*this)); if (Res.mData_ && Res.mLen_) { mData_ = new BYTE[Res.mLen_ + 1]; if ( mData_ ) { CopyMemory( mData_, Res.mData_, Res.mLen_); mLen_ = Res.mLen_; } CopyMemory( mName, Res.mName, 50); } } ~CPropertyRes(void) { if (mData_) { delete[] (char*)mData_; mData_ = NULL; } mLen_ = NULL; ZeroMemory(this,sizeof(*this)); } void Init() { mData_ = NULL; mLen_ = 0; } TCHAR* GetFileName() { return (TCHAR*)mData_; } char* GetProcessName() { return (char*)mData_; } TCHAR* GetQueryDomainName() { return (TCHAR*)mData_; } TCHAR* GetQueryResult() { return (TCHAR*)mData_; } ULONGLONG GetFileObject() { if ( mData_ ) { return *((ULONGLONG*)mData_); } return 0; } ULONG GetProcessId() { if ( mData_ ) { return *((ULONG*)mData_); } return -1; } WORD GetPort() { if ( mData_ ) { return *((WORD*)mData_); } return -1; } ULONG GetQueryStatus() { if ( mData_ ) { return *((ULONG*)mData_); } return -1; } ULONG GetIpAddress() { if ( mData_ ) { return *((ULONG*)mData_); } return -1; } ULONG GetIoSize() { if ( mData_ ) { return *((ULONG*)mData_); } return 0; } BOOL operator == ( TCHAR* StrName) { if (!wcsicmp(StrName,mName)) { return TRUE; } return FALSE; } private: TCHAR mName[50]; PBYTE mData_; int mLen_; }; #define PARSE_TYPE_FILE 1 #define PARSE_TYPE_OTHER 2 static CPropertyRes Res; #endif ================================================ FILE: Sysmon/CSsymonEtw.cpp ================================================ #include "StdAfx.h" #include "CSsymonEtw.h" #include "CSysmonUtil.h" #include #include #include #pragma comment(lib,"Ws2_32.lib") #define EVENT_TRACE_SYSTEM_LOGGER_MODE 0x2000000 CSsymonEtw* CSsymonEtw::_Instace = NULL; CSsymonEtw::CSsymonEtw(void) { m_pStartTrace = NULL; m_pControlTrace = NULL; m_pOpenTrace = NULL; m_pProcessTrace = NULL; m_SessionHandle = NULL; m_hEtwTraceThread =0; m_bInit = FALSE; m_hGlobalEvent = CreateEvent(0, TRUE, 0, 0); m_bStartTrace = FALSE; m_bInitData = FALSE; m_EventClassNums = 0; GetSystemTimeAsFileTime(&m_SystemTime); QueryPerformanceCounter(&m_PerformanceCount); QueryPerformanceFrequency(&m_Frequency); } CSsymonEtw::~CSsymonEtw(void) { } ULONG CSsymonEtw::InitData() { FILETIME SystemTimeAsFileTime; if ( CSsymonEtw::m_bInitData ) { //sub_4144E0(1); } else { InitializeCriticalSection(&m_csData); CSsymonEtw::m_bInitData = 1; } GetSystemTimeAsFileTime(&SystemTimeAsFileTime); m_SystemTime = SystemTimeAsFileTime; return SystemTimeAsFileTime.dwHighDateTime; } void CSsymonEtw::Enter() { EnterCriticalSection(&m_csData); } void CSsymonEtw::Leave() { LeaveCriticalSection(&m_csData); } HRESULT CSsymonEtw::StartTrace(BOOL bStart) { WSAData Wsa = {0}; BOOL IsThanXp = FALSE; DWORD dwVerison = GetVersion(); DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVerison))); DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVerison))); DWORD FileMode = 0; UINT ThreadId; HRESULT bFail; if (m_bInit == FALSE) { HMODULE hAdv = LoadLibraryW(L"advapi32.dll"); m_pStartTrace = (pStartTrace)GetProcAddress(hAdv, "StartTraceW"); m_pControlTrace = (pControlTrace)GetProcAddress(hAdv, "ControlTraceW"); m_pOpenTrace = (pOpenTrace)GetProcAddress(hAdv, "OpenTraceW"); m_pProcessTrace = (pProcessTrace)GetProcAddress(hAdv, "ProcessTrace"); int ret = WSAStartup( MAKEWORD(2,2), &Wsa); if ( ret ) return ret; m_bInit = TRUE; } if (!m_pStartTrace) { return 1; } if (m_bStartTrace == bStart) { return 0; } if (dwMajorVersion >= 6 ) { if(dwMinorVersion >= 2) { IsThanXp = TRUE; } } Sysomn_Event_Properties SysmonEvent = {0}; SysmonEvent.Properties.Wnode.BufferSize = sizeof(Sysomn_Event_Properties); SysmonEvent.Properties.Wnode.Flags = WNODE_FLAG_TRACED_GUID ; SysmonEvent.Properties.Wnode.ClientContext = 1; SysmonEvent.Properties.FlushTimer = 1; SysmonEvent.Properties.LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES); SysmonEvent.Properties.LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES) + MAX_PATH*sizeof(TCHAR); FileMode = 0; if (IsThanXp) { FileMode = EVENT_TRACE_SYSTEM_LOGGER_MODE; } SysmonEvent.Properties.LogFileMode = FileMode | EVENT_TRACE_REAL_TIME_MODE; if ( dwMajorVersion < 6 || dwMinorVersion < 2) { SysmonEvent.Properties.Wnode.Guid = SystemTraceControlGuid; } LPCTSTR pLogName = _T("SYSMON TRACE"); if (!IsThanXp) { pLogName = _T("NT Kernel Logger"); } StringCchCopy(SysmonEvent.LoggerName,MAX_PATH,pLogName ); if (CSysmonUtil::SysmonVersionIsSupport()) { SysmonEvent.Properties.EnableFlags = EVENT_TRACE_FLAG_EXTENSION; SysmonEvent.Properties.EnableFlags |= 0x00FF0000; SysmonEvent.Properties.EnableFlags |= (EVENT_TRACE_FLAG_DISK_IO_INIT | EVENT_TRACE_FLAG_SYSTEMCALL | EVENT_TRACE_FLAG_PROCESS_COUNTERS); SysmonEvent.dwMax2 = 0x10009; SysmonEvent.dwMax1 = 0x1000A; SysmonEvent.dwMax3 = 0x10000; } else { SysmonEvent.Properties.EnableFlags |= EVENT_TRACE_FLAG_NETWORK_TCPIP; } if (bStart) { InitData(); ULONG bSuccess = m_pStartTrace( &m_SessionHandle, SysmonEvent.LoggerName, &SysmonEvent.Properties); if ( bSuccess && bSuccess != ERROR_ALREADY_EXISTS) { //sub_418280(&Text, L"Network trace initialization failed: Error %d", v11); //MessageBoxW(0, &Text, L"System Monitor", 0x10u); bFail = bSuccess; } else { m_hEtwTraceThread = (HANDLE) _beginthreadex( 0, 0, CSsymonEtw::ProcessTraceThread, 0, 0, &ThreadId); m_bStartTrace = bStart; bFail = 0; } } else { SetEvent(m_hGlobalEvent); bFail = m_pControlTrace( m_SessionHandle, SysmonEvent.LoggerName, &SysmonEvent.Properties, EVENT_TRACE_CONTROL_STOP); WaitForSingleObject(m_hEtwTraceThread, INFINITE); CloseHandle(m_hEtwTraceThread); m_hEtwTraceThread = 0; ResetEvent(m_hGlobalEvent); if ( !bFail ) { m_bStartTrace = 0; //sub_414630(); } } return bFail; } void* CSsymonEtw::GetEventClassPropertyListList(PEVENT_TRACE pEventTrace) { if (!m_EventClassNums) { //EventTraceGuid m_EventClassNums++; } if (pEventTrace) { } return 0; } UINT CSsymonEtw::ProcessTraceThread(void* lp) { BOOL IsThanXp = FALSE; BOOL IsStop = FALSE; DWORD dwVerison = GetVersion(); DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVerison))); DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVerison))); if (dwMajorVersion >= 6 ) { if(dwMinorVersion >= 2) { IsThanXp = TRUE; } } EVENT_TRACE_LOGFILE SysmonEvent = {0}; SysmonEvent.LoggerName = NULL; SysmonEvent.Context = 0; SysmonEvent.BufferCallback = CSsymonEtw::BufferCallback; SysmonEvent.BuffersRead = 0; LPCTSTR pLogName = _T("SYSMON TRACE"); if (!IsThanXp) { pLogName = _T("NT Kernel Logger"); } SysmonEvent.LoggerName = (LPWSTR)pLogName; SysmonEvent.CurrentTime = 0; SysmonEvent.EventCallback = CSsymonEtw::EventCallback; SysmonEvent.LogFileMode = EVENT_TRACE_REAL_TIME_MODE | EVENT_TRACE_ADD_HEADER_MODE; TRACEHANDLE hOpenTrace = CSsymonEtw::Instance()->m_pOpenTrace(&SysmonEvent); if (!hOpenTrace) { return -1; } UINT ThreadId = 0; HANDLE hDataThread = (void *)_beginthreadex( 0, 0, ProcessDataThread, 0, 0, &ThreadId); ULONG bSuccess = CSsymonEtw::Instance()->m_pProcessTrace( &hOpenTrace, 1, 0, 0); if ( WaitForSingleObject( CSsymonEtw::Instance()->m_hGlobalEvent, 0) == STATUS_TIMEOUT ) { IsStop = 1; SetEvent(CSsymonEtw::Instance()->m_hGlobalEvent); } WaitForSingleObject(hDataThread, INFINITE); CloseHandle(hDataThread); if ( IsStop ) { CloseHandle(CSsymonEtw::Instance()->m_hEtwTraceThread); CSsymonEtw::Instance()->m_hEtwTraceThread = 0; ResetEvent(CSsymonEtw::Instance()->m_hGlobalEvent); CSsymonEtw::Instance()->m_bStartTrace = 0; //sub_414630(); // if ( sub_407C70() & 1 ) CSsymonEtw::Instance()->StartTrace(1); } return 0; } ULONG CSsymonEtw::BufferCallback( PEVENT_TRACE_LOGFILE Buffer ) { return 0; } #include "CMofDataParser.h" VOID CSsymonEtw::EventCallback( PEVENT_TRACE pEvent ) { if (pEvent) { //CMofParseRes Result; //CSsymonEtw::Instance()->m_MofDataParser.Parse(pEvent,Result); return; CSysmonDataEntry* pDataEntry = CSsymonEtw::Instance()->m_SysmonMofData.Phase_1( &pEvent->Header.Guid, pEvent->Header.Class.Version, pEvent->Header.Class.Level, pEvent->Header.Class.Type); if (pDataEntry) { CSsymonEtw::Instance()->Enter(); CSsymonEtw::Instance()->m_SysmonMofData.Phase_2(pEvent,pDataEntry); CSsymonEtw::Instance()->Leave(); } } } UINT CSsymonEtw::ProcessDataThread(void* lp) { LARGE_INTEGER PerformanceCount; while ( WaitForSingleObject( CSsymonEtw::Instance()->m_hGlobalEvent, 250) == STATUS_TIMEOUT ) { CSsymonEtw::Instance()->Enter(); QueryPerformanceCounter(&PerformanceCount); ULONG LowPart = PerformanceCount.LowPart - CSsymonEtw::Instance()->m_PerformanceCount.LowPart; ULONG HighPart = (PerformanceCount.HighPart - CSsymonEtw::Instance()->m_PerformanceCount.HighPart); ULONGLONG QuadPart = PerformanceCount.QuadPart - CSsymonEtw::Instance()->m_PerformanceCount.QuadPart; ULONGLONG Frequency = 0; LARGE_INTEGER ft2 = {0}; LARGE_INTEGER lg2 = {0}; LARGE_INTEGER lg3 = {0}; if ( HighPart >= 0 ) { lg2.QuadPart = ((10000000 * (QuadPart % CSsymonEtw::Instance()->m_Frequency.QuadPart)) / CSsymonEtw::Instance()->m_Frequency.QuadPart + 10000000 * (QuadPart / CSsymonEtw::Instance()->m_Frequency.QuadPart)); ft2.LowPart = lg2.LowPart; } else { lg2.QuadPart = CSysmonUtil::CounterTimes( CSsymonEtw::Instance()->m_SystemTime, -HighPart); ft2.LowPart = lg2.LowPart; } ft2.HighPart = CSsymonEtw::Instance()->m_SystemTime.dwHighDateTime; lg3.LowPart += CSsymonEtw::Instance()->m_SystemTime.dwLowDateTime; lg2.LowPart = CSsymonEtw::Instance()->m_SystemTime.dwLowDateTime; ft2.HighPart = (ft2.QuadPart + lg2.QuadPart) >> 32; CSsymonEtw::Instance()->Leave(); } return 0; } ================================================ FILE: Sysmon/CSsymonEtw.h ================================================ #ifndef _CSsymonEtw_h #define _CSsymonEtw_h #include "CMofDataParser.h" #include "CSysmonMofData.h" #include #include typedef void* HEVENT; #ifdef __cplusplus extern "C"{ #endif typedef ULONG (WINAPI *pStartTrace)( PTRACEHANDLE SessionHandle, LPCTSTR SessionName, PEVENT_TRACE_PROPERTIES Properties ); typedef ULONG (WINAPI *pControlTrace) ( TRACEHANDLE SessionHandle, LPCTSTR SessionName, PEVENT_TRACE_PROPERTIES Properties, ULONG ControlCode ); typedef TRACEHANDLE (WINAPI *pOpenTrace) ( PEVENT_TRACE_LOGFILE Logfile ); typedef ULONG (WINAPI *pProcessTrace)( _In_ PTRACEHANDLE HandleArray, _In_ ULONG HandleCount, _In_ LPFILETIME StartTime, _In_ LPFILETIME EndTime ); #ifdef __cplusplus }; #endif typedef struct _Sysomn_Event_Properties { EVENT_TRACE_PROPERTIES Properties; TCHAR LoggerName[MAX_PATH]; TCHAR LoggerFile[MAX_PATH]; ULONG dwMax1; ULONG dwMax2; ULONG dwMax3; ULONG dwMax4; ULONG dwMax5; ULONG dwMax6; ULONG dwMax7; ULONG dwMax8; ULONG dwMax9; ULONG dwMax10; }Sysomn_Event_Properties; class CSsymonEtw { public: CSsymonEtw(void); virtual ~CSsymonEtw(void); public: HRESULT StartTrace(BOOL bStart); ULONG InitData(); void* GetEventClassPropertyListList(PEVENT_TRACE pEventTrace); void Enter(); void Leave(); public: pStartTrace m_pStartTrace; pControlTrace m_pControlTrace; pOpenTrace m_pOpenTrace; pProcessTrace m_pProcessTrace; BOOL m_bInit; BOOL m_bStartTrace; TRACEHANDLE m_SessionHandle; HANDLE m_hEtwTraceThread; HEVENT m_hGlobalEvent; BOOL m_bInitData; CRITICAL_SECTION m_csData; FILETIME m_SystemTime; LARGE_INTEGER m_PerformanceCount; LARGE_INTEGER m_Frequency; UINT64 m_EventClassNums; CSysmonMofData m_SysmonMofData; CMofDataParser m_MofDataParser; private: static UINT WINAPI ProcessTraceThread(void* lp); static UINT WINAPI ProcessDataThread(void* lp); static ULONG WINAPI BufferCallback( PEVENT_TRACE_LOGFILE Buffer ); static VOID WINAPI EventCallback( PEVENT_TRACE pEvent ); public: static CSsymonEtw* Instance() { if (!_Instace) { _Instace = new CSsymonEtw(); } return _Instace; } static CSsymonEtw* _Instace; }; #endif ================================================ FILE: Sysmon/CSysmonDriverOpt.cpp ================================================ #include "StdAfx.h" #include "CSysmonDriverOpt.h" CSysmonDriverOpt::CSysmonDriverOpt(void) { } CSysmonDriverOpt::~CSysmonDriverOpt(void) { } //======================================== ̬/жsys ====================================== // SYSļͬĿ¼ // SYSΪHelloDDK.sys,ôװInstallDriver("HelloDDK",".\\HelloDDK.sys","370030"/*Altitude*/); // StartDriver("HelloDDK"); // ֹͣ StopDriver("HelloDDK"); // жSYSҲƵĵụ̀ DeleteDriver("HelloDDK"); //==================================================================================================== BOOL CSysmonDriverOpt::InstallDriver( LPCTSTR lpszDriverName, LPCTSTR lpszDriverPath, LPCTSTR lpszAltitude) { TCHAR szTempStr[MAX_PATH]; HKEY hKey; DWORD dwData; TCHAR szDriverImagePath[MAX_PATH]; if( NULL == lpszDriverName || NULL == lpszDriverPath ) { return FALSE; } //õ· GetFullPathName( lpszDriverPath, MAX_PATH, szDriverImagePath, NULL); SC_HANDLE hServiceMgr = NULL; SC_HANDLE hService = NULL; //򿪷ƹ hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if( hServiceMgr == NULL ) { CloseServiceHandle(hServiceMgr); return FALSE; } //Ӧķ hService = CreateService( hServiceMgr, lpszDriverName, // עе lpszDriverName, // עDisplayName ֵ SERVICE_ALL_ACCESS, // ķȨ SERVICE_FILE_SYSTEM_DRIVER, // ʾصķļϵͳ SERVICE_DEMAND_START, // עStart ֵ SERVICE_ERROR_IGNORE, // עErrorControl ֵ szDriverImagePath, // עImagePath ֵ _T("FSFilter Activity Monitor"),// עGroup ֵ NULL, _T("FltMgr"), // עDependOnService ֵ NULL, NULL); if( hService == NULL ) { if( GetLastError() == ERROR_SERVICE_EXISTS ) { //񴴽ʧܣڷѾ CloseServiceHandle(hService); // CloseServiceHandle(hServiceMgr); // SCM return TRUE; } else { CloseServiceHandle(hService); // CloseServiceHandle(hServiceMgr); // SCM return FALSE; } } CloseServiceHandle(hService); // CloseServiceHandle(hServiceMgr); // SCM //------------------------------------------------------------------------------------------------------- // SYSTEM\\CurrentControlSet\\Services\\DriverName\\Instancesӽµļֵ //------------------------------------------------------------------------------------------------------- lstrcpy(szTempStr,_T("SYSTEM\\CurrentControlSet\\Services\\")); lstrcat(szTempStr,lpszDriverName); lstrcat(szTempStr,_T("\\Instances")); if(RegCreateKeyEx( HKEY_LOCAL_MACHINE, szTempStr, 0, _T(""), TRUE, KEY_ALL_ACCESS, NULL, &hKey, (LPDWORD)&dwData)!=ERROR_SUCCESS) { return FALSE; } // עDefaultInstance ֵ lstrcpy(szTempStr,lpszDriverName); lstrcat(szTempStr,_T("Instance")); if(RegSetValueEx( hKey, _T("DefaultInstance"), 0, REG_SZ, (CONST BYTE*) szTempStr, (DWORD)lstrlen(szTempStr)*sizeof(TCHAR))!=ERROR_SUCCESS) { return FALSE; } RegFlushKey(hKey);//ˢע RegCloseKey(hKey); //------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------- // SYSTEM\\CurrentControlSet\\Services\\DriverName\\Instances\\DriverName Instanceӽµļֵ //------------------------------------------------------------------------------------------------------- lstrcpy(szTempStr,_T("SYSTEM\\CurrentControlSet\\Services\\")); lstrcat(szTempStr,lpszDriverName); lstrcat(szTempStr,_T("\\Instances\\")); lstrcat(szTempStr,lpszDriverName); lstrcat(szTempStr,_T("Instance")); if(RegCreateKeyEx( HKEY_LOCAL_MACHINE, szTempStr, 0, _T(""), TRUE, KEY_ALL_ACCESS, NULL, &hKey, (LPDWORD)&dwData)!=ERROR_SUCCESS) { return FALSE; } // עAltitude ֵ lstrcpy(szTempStr,lpszAltitude); if(RegSetValueEx( hKey, _T("Altitude"), 0, REG_SZ, (CONST BYTE*)szTempStr, (DWORD) lstrlen(szTempStr)*sizeof(TCHAR))!=ERROR_SUCCESS) { return FALSE; } // עFlags ֵ dwData = 0x0; if(RegSetValueEx( hKey, _T("Flags"), 0, REG_DWORD, (CONST BYTE*)&dwData, sizeof(DWORD))!=ERROR_SUCCESS) { return FALSE; } RegFlushKey(hKey);//ˢע RegCloseKey(hKey); //------------------------------------------------------------------------------------------------------- return TRUE; } BOOL CSysmonDriverOpt::StartDriver(LPCTSTR lpszDriverName) { SC_HANDLE schManager; SC_HANDLE schService; SERVICE_STATUS svcStatus; if( NULL == lpszDriverName) { return FALSE; } schManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS); if(NULL == schManager) { CloseServiceHandle(schManager); return FALSE; } schService = OpenService( schManager, lpszDriverName, SERVICE_ALL_ACCESS); if(NULL == schService) { CloseServiceHandle(schService); CloseServiceHandle(schManager); return FALSE; } if(!StartService( schService, 0, NULL)) { CloseServiceHandle(schService); CloseServiceHandle(schManager); DWORD dwError = GetLastError(); if( dwError == ERROR_SERVICE_ALREADY_RUNNING ) { return TRUE; } TCHAR szError[50]; wsprintf(szError,_T("%d"),dwError); MessageBox(NULL,szError,szError,MB_OK); return FALSE; } CloseServiceHandle(schService); CloseServiceHandle(schManager); return TRUE; } BOOL CSysmonDriverOpt::StopDriver(LPCTSTR lpszDriverName) { SC_HANDLE schManager; SC_HANDLE schService; SERVICE_STATUS svcStatus; bool bStopped=false; schManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS); if(NULL == schManager) { return FALSE; } schService = OpenService( schManager, lpszDriverName, SERVICE_ALL_ACCESS); if(NULL == schService) { CloseServiceHandle(schManager); return FALSE; } if(!ControlService( schService, SERVICE_CONTROL_STOP, &svcStatus) && (svcStatus.dwCurrentState != SERVICE_STOPPED)) { CloseServiceHandle(schService); CloseServiceHandle(schManager); return FALSE; } CloseServiceHandle(schService); CloseServiceHandle(schManager); return TRUE; } BOOL CSysmonDriverOpt::DeleteDriver(LPCTSTR lpszDriverName) { SC_HANDLE schManager; SC_HANDLE schService; SERVICE_STATUS svcStatus; schManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS); if(NULL == schManager) { return FALSE; } schService = OpenService( schManager, lpszDriverName, SERVICE_ALL_ACCESS); if(NULL == schService) { CloseServiceHandle(schManager); return FALSE; } ControlService( schService, SERVICE_CONTROL_STOP, &svcStatus); if(!DeleteService(schService)) { CloseServiceHandle(schService); CloseServiceHandle(schManager); return FALSE; } CloseServiceHandle(schService); CloseServiceHandle(schManager); return TRUE; } ================================================ FILE: Sysmon/CSysmonDriverOpt.h ================================================ #ifndef _CSysmonDriverOpt_h #define _CSysmonDriverOpt_h class CSysmonDriverOpt { public: CSysmonDriverOpt(void); virtual ~CSysmonDriverOpt(void); public: BOOL InstallDriver( LPCTSTR lpszDriverName, LPCTSTR lpszDriverPath, LPCTSTR lpszAltitude); BOOL StartDriver(LPCTSTR lpszDriverName); BOOL StopDriver(LPCTSTR lpszDriverName); BOOL DeleteDriver(LPCTSTR lpszDriverName); }; #endif ================================================ FILE: Sysmon/CSysmonMofData.cpp ================================================ #include "StdAfx.h" #include "CSysmonMofData.h" #include "CSsymonEtw.h" #include "CSysmonUtil.h" #include "Sysmon.h" #define MAX_MOF_DATA_LIST 357913940 CTcpIpInfo CSysmonMofData::m_TcpIpEventTypeName[25] = { {_T("Send"),2}, {_T("SendIPV4"),2}, {_T("SendIPV6"),2}, {_T("Recv"),3}, {_T("RecvIPV4"),3}, {_T("RecvIPV6"),3}, {_T("Accept"),4}, {_T("AcceptIPV4"),4}, {_T("AcceptIPV6"),4}, {_T("Connect"),5}, {_T("ConnectIPV4"),5}, {_T("ConnectIPV6"),5}, {_T("Disconnect"),6}, {_T("DisconnectIPV4"),6}, {_T("DisconnectIPV6"),6}, {_T("Reconnect"),7}, {_T("ReconnectIPV4"),7}, {_T("ReconnectIPV6"),7}, {_T("Retransmit"),8}, {_T("RetransmitIPV4"),8}, {_T("RetransmitIPV6"),8}, {_T("TCPCopy"),9}, {_T("TCPCopyIPV4"),9}, {_T("TCPCopyIPV6"),9} }; CSysmonMofData::CSysmonMofData(void) :m_pIWbemService(NULL) ,m_EventListNums(0) { m_SysmonEventList = new CSysmonEventList(0,0); } CSysmonMofData::~CSysmonMofData(void) { if (m_SysmonEventList) { delete m_SysmonEventList; m_SysmonEventList = NULL; } } HRESULT CSysmonMofData::CoCreateInstance() { OLECHAR *pwWdmi; HRESULT hr; IWbemLocator *pLocator; pLocator = 0; pwWdmi = SysAllocString(L"root\\wmi"); CoInitializeEx(0, 0); hr = ::CoCreateInstance( __uuidof(WbemLocator), 0, CLSCTX_INPROC_SERVER, __uuidof(IWbemLocator), (LPVOID *)&pLocator); if ( SUCCEEDED(hr) ) { hr = pLocator->ConnectServer( pwWdmi, NULL, NULL, NULL, 0L, NULL, NULL, &m_pIWbemService); if ( SUCCEEDED(hr) ) hr = CoSetProxyBlanket( m_pIWbemService, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, 0, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, 0, EOAC_NONE); } SysFreeString(pwWdmi); if ( pLocator ) pLocator->Release(); return hr; } CSysmonDataEntry* CSysmonMofData::Phase_1( GUID* ClassGuid, USHORT Version, USHORT Level, USHORT Type) { CSysmonDataEntry* pDataEntry = NULL; LONG nIndex = 0; do { if ( !m_EventListNums ) { CSysmonDataEntry* pDataEntry_1 = new CSysmonDataEntry( (GUID*)&EventTraceGuid, -1, 0, 0); if ( pDataEntry_1 ) { pDataEntry_1->InitData(&pDataEntry_1->m_EventClassName, L"EventTrace"); pDataEntry_1->InitData(&pDataEntry_1->m_EventTypeName, L"Header"); CSysmonEventList* pEventList = m_SysmonEventList->InsertBack( m_SysmonEventList->m_Entry.Blink, pDataEntry_1); if ( (unsigned int)(MAX_MOF_DATA_LIST - m_EventListNums) < 1 ) { //std::_Xlength_error("list too long"); } ++m_EventListNums; m_SysmonEventList->m_Entry.Blink = &pEventList->m_Entry; pEventList->m_Entry.Blink->Flink = &pEventList->m_Entry; } } if ( !IsListEmpty(&m_SysmonEventList->m_Entry) ) { LIST_ENTRY* pEntry = m_SysmonEventList->m_Entry.Flink; CSysmonDataEntry* pTem_2 = NULL; CSysmonDataEntry* pTem_3 = NULL; while(TRUE) { CSysmonEventList* pList = CONTAINING_RECORD(pEntry,CSysmonEventList,m_Entry); CSysmonDataEntry* pTemp = (CSysmonDataEntry*)pList->m_pEvent; int TotleSize = 12; if (pTemp) { LONG* p1 = (LONG*)&(pTemp->m_EventGuid); LONG* p2 = (LONG*)ClassGuid; while( *p1 == *p2) { p1++; p2++; BOOL bExit = TotleSize < 4; TotleSize -= 4; if (bExit) { if ( pTemp->m_EventType == Type && pTemp->m_EventVersion == Version) { pDataEntry = pTemp; return pDataEntry; } if (pTemp->m_EventType == 0x0FFFF ) { if (!pTem_2) { pTem_2 = pTemp; } } break; } } } pEntry = pEntry->Flink; if (pEntry != &m_SysmonEventList->m_Entry) { continue; } break; } } if (!pDataEntry) { pDataEntry = GetEventCategoryClass(ClassGuid,Version,Level,Type); if (!pDataEntry) { pDataEntry = new CSysmonDataEntry( ClassGuid, Type, Version, Level); if ( pDataEntry ) { pDataEntry->m_EventClassName = NULL; pDataEntry->m_EventTypeName = NULL; pDataEntry->m_ProperityList = 0; pDataEntry->m_ProperitySize = 0; } } } } while (FALSE); return pDataEntry; } void CSysmonMofData::Phase_2( PEVENT_TRACE pEvent, CSysmonDataEntry* pDataEntry ) { LARGE_INTEGER SystemTime; LARGE_INTEGER SystemTime_2; __try { if (pEvent && pDataEntry) { if (pEvent->MofData && pEvent->MofLength) { CSysmonData* pEventClass = pDataEntry->m_EventClassName; ULONG dwClassType = 0; if (pEventClass && pEventClass->Compare(_T("TcpIp"))) { dwClassType = 1; } else if (pEventClass && pEventClass->Compare(_T("UdpIp"))) { dwClassType = 2; } else if (pEventClass && pEventClass->Compare(_T("MSNT_TcpIpInformation"))) { dwClassType = 3; } if ( dwClassType == 1 || dwClassType == 2 || dwClassType == 3 ) { BOOL v15 = (pEvent->Header.TimeStamp.HighPart == 0x1000000); BOOL v16 = (pEvent->Header.TimeStamp.HighPart > 0x1000000); if (pEvent->Header.TimeStamp.HighPart < 0x1000000 || pEvent->Header.TimeStamp.LowPart < 0 ) { SystemTime.QuadPart = CSysmonUtil::CounterTimes( CSsymonEtw::Instance()->m_SystemTime, pEvent->Header.TimeStamp.QuadPart - CSsymonEtw::Instance()->m_PerformanceCount.QuadPart ); SystemTime_2.LowPart = CSsymonEtw::Instance()->m_SystemTime.dwLowDateTime; SystemTime_2.HighPart = CSsymonEtw::Instance()->m_SystemTime.dwHighDateTime; SystemTime_2.QuadPart += SystemTime.QuadPart; SystemTime.LowPart = CSsymonEtw::Instance()->m_SystemTime.dwLowDateTime; SystemTime.HighPart = CSsymonEtw::Instance()->m_SystemTime.dwHighDateTime; } else { SystemTime_2.HighPart = pEvent->Header.TimeStamp.HighPart; SystemTime_2.LowPart = pEvent->Header.TimeStamp.LowPart; SystemTime.LowPart = CSsymonEtw::Instance()->m_SystemTime.dwLowDateTime; SystemTime.HighPart = CSsymonEtw::Instance()->m_SystemTime.dwHighDateTime; } if (SystemTime_2.QuadPart >= SystemTime.QuadPart) { CSysmonData* pEventType = pDataEntry->m_EventTypeName; LONG EventType = 0; BOOL IsUdp = FALSE; __try { IsUdp = pEventClass->CompareN(_T("Udp"),3); } __except(EXCEPTION_EXECUTE_HANDLER) { IsUdp = FALSE; } if (pEventType && pEventType->Len()) { LONG nI = 0; BOOL NotEque = TRUE; __try { while(TRUE && nI < 24) { BSTR pEventTypeName_1 = CSysmonMofData::m_TcpIpEventTypeName[nI].NetName; BSTR pEventTypeName_2 = pEventType->m_pData; while(TRUE && pEventTypeName_1 && pEventTypeName_2) { if (pEventTypeName_1[0] != pEventTypeName_2[0]) { break; } if (pEventTypeName_1[0] == 0) { NotEque = FALSE; break; } pEventTypeName_1++; pEventTypeName_2++; } if (NotEque == FALSE) { break; } nI++; if (nI > 24) { EventType = 0; __leave; } } EventType = CSysmonMofData::m_TcpIpEventTypeName[nI].NetType; } __except(EXCEPTION_EXECUTE_HANDLER) { } } else { EventType = (pEvent->Header.Class.Type==11)?3:(pEvent->Header.Class.Type==10)+1; } if (IsUdp == TRUE || EventType == 4 || EventType == 5) { if ( pDataEntry->m_ProperityList && !pDataEntry->m_ProperityList->IsListEmpty()) { __try { Sysmon_Net_Report* NetReport = (Sysmon_Net_Report*) malloc(sizeof(Sysmon_Net_Report)); if (NetReport) { NetReport->NrEventType = 1; NetReport->NrProcessId = pEvent->Header.ProcessId; if (pEvent->Header.ThreadId == -1) { NetReport->NrThreadId = 0; } else { NetReport->NrThreadId = pEvent->Header.ThreadId; } __m128i m128Zero = {0}; _mm_storeu_si128((__m128i *)&NetReport->NrGuid, m128Zero); } } __except(EXCEPTION_EXECUTE_HANDLER) { } } } } } } } } __except(EXCEPTION_EXECUTE_HANDLER) { } } CSysmonDataEntry* CSysmonMofData::GetEventCategoryClass( GUID* ClassGuid, USHORT Version, USHORT Level, USHORT Type) { HRESULT hr = S_OK; OLECHAR* oleTrace = NULL; OLECHAR* oleClassName = NULL; OLECHAR* oleGuid = NULL; OLECHAR* oleVersion = NULL; VARIANT varGuid; VARIANT varVersion; VARIANT varClassName; CSysmonDataEntry* pDataEntry; OLECHAR* oleClassName_2 = NULL; pDataEntry = NULL; IEnumWbemClassObject* pClasses = NULL; IEnumWbemClassObject* pClasses_2 = NULL; IWbemClassObject* pClass = NULL; IWbemClassObject* pClass_2 = NULL; IWbemQualifierSet* pQualifiers = NULL; ULONG CntTrace = 1; ULONG CntClass = 1; TCHAR EventGuid[5*sizeof(GUID)] = {0}; TCHAR GuidString[5*sizeof(GUID)] = {0}; VariantInit(&varClassName); VariantInit(&varGuid); VariantInit(&varVersion); do { if (!m_pIWbemService && CoCreateInstance()) { break; } StringCchPrintf( EventGuid, 5*sizeof(GUID), _T("{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"), ClassGuid->Data1, ClassGuid->Data2, ClassGuid->Data3, ClassGuid->Data4[0], ClassGuid->Data4[1], ClassGuid->Data4[2], ClassGuid->Data4[3], ClassGuid->Data4[4], ClassGuid->Data4[5], ClassGuid->Data4[6], ClassGuid->Data4[7]); oleTrace = SysAllocString(_T("EventTrace")); oleClassName = SysAllocString(_T("__CLASS")); oleGuid = SysAllocString(_T("Guid")); oleVersion = SysAllocString(_T("EventVersion")); hr = m_pIWbemService->CreateClassEnum( oleTrace, WBEM_FLAG_DEEP | WBEM_FLAG_UPDATE_ONLY | WBEM_FLAG_USE_AMENDED_QUALIFIERS, 0, &pClasses); SysFreeString(oleTrace); if (hr != S_OK) { break; } __try { do { if (pClass) { pClass->Release(); pClass = NULL; } if( pClasses->Next(5000,1, &pClass, &CntTrace) != S_OK) { continue; } if (CntTrace != 1) { break; } if ( pClass->Get(oleClassName, 0, &varClassName, 0, 0) != S_OK ) continue; oleClassName_2 = SysAllocString(varClassName.bstrVal); m_pIWbemService->CreateClassEnum( oleClassName_2, WBEM_FLAG_DEEP | WBEM_FLAG_UPDATE_ONLY | WBEM_FLAG_USE_AMENDED_QUALIFIERS, 0, &pClasses_2); SysFreeString(oleClassName_2); VariantClear(&varClassName); CntClass = 1; do { pClass_2 = NULL; if (pClasses_2) { if ( pClasses_2->Next(5000, 1, &pClass_2, &CntClass) != S_OK ) continue; if ( CntClass != 1 ) break; } else { CntClass = 1; pClass_2 = pClass; } HRESULT hr2 = pClass_2->Get(oleClassName, 0, &varClassName, 0, 0); VariantClear(&varClassName); if (hr2 == S_OK) { if ( pQualifiers ) { pQualifiers->Release(); pQualifiers = 0; } HRESULT hrQualifier = pClass_2->GetQualifierSet(&pQualifiers); if ( FAILED(hrQualifier)) { break; } if(pQualifiers->Get( oleGuid, 0, &varGuid, 0) == S_OK) { wcscpy_s(GuidString, 5*sizeof(GUID), varGuid.bstrVal); VariantClear(&varGuid); if ( !wcsstr(GuidString, L"{") ) StringCchPrintf(GuidString, 5*sizeof(GUID),_T("{%s}"),GuidString); if ( !_wcsicmp(GuidString, EventGuid) ) { if(pQualifiers->Get( oleVersion, 0, &varVersion, 0) == S_OK) { VariantChangeType(&varVersion, &varVersion, 0, VT_I2); WORD VersionTmp = varVersion.iVal; VariantClear(&varVersion); if ( Version != VersionTmp ) continue; pDataEntry = GetPropertyList( pClass_2, ClassGuid, Version, Level, Type); } else { pDataEntry = GetPropertyList( pClass_2, ClassGuid, Version, Level, Type); } __leave; } } } } while (CntClass == 1); if (pClasses_2) { pClasses_2->Release(); pClasses_2 = NULL; } } while (CntTrace == 1); } __except(EXCEPTION_EXECUTE_HANDLER) { } if (pClasses) { pClasses->Release(); pClasses = NULL; } } while (FALSE); VariantClear(&varGuid); VariantClear(&varVersion); SysFreeString(oleGuid); SysFreeString(oleClassName); SysFreeString(oleVersion); if (pClasses) { pClasses->Release(); pClasses = NULL; } if (pClasses_2) { pClasses_2->Release(); pClasses_2 = NULL; } if (pQualifiers) { pQualifiers->Release(); pQualifiers = NULL; } return pDataEntry; } void CSysmonMofData::InsertBack( CSysmonEventList* pEventList, LONG* Reference, void* pElm) { CSysmonEventList* pNewList = pEventList->InsertBack(pEventList->m_Entry.Blink,pElm); (*Reference)++; if ( 0x15555554 - *Reference < 1 ) { //std::_Xlength_error("list too long"); } (*Reference)++; pEventList->m_Entry.Blink = &pNewList->m_Entry; pNewList->m_Entry.Blink->Flink = &pNewList->m_Entry; } void CSysmonDataEntry::operator =(CSysmonDataEntry* pDataEntry) { if (this != pDataEntry) { m_EventClassName = pDataEntry->m_EventClassName; if ( pDataEntry->m_EventClassName ) InterlockedIncrement((volatile LONG *)&m_EventClassName->m_Reference); } } void CSysmonMofData::SysmonAddProperityList( CSysmonEventList* pList, BSTR ProperityName, LONG Len, LONG ArraySize) { if ( pList) { LONG Reference = 0; LIST_ENTRY* pEntry = pList->m_Entry.Flink; while( pEntry != &pList->m_Entry) { CSysmonEventList* pEventList = CONTAINING_RECORD(pEntry,CSysmonEventList,m_Entry); if (pEventList) { CSysmonDataEntry* pDataEntry = (CSysmonDataEntry*)pEventList->m_pEvent; if (pDataEntry) { CSysmonProperty* pProperity = new CSysmonProperty(ProperityName,Len,ArraySize); pDataEntry->m_ProperitySize++; CSysmonEventList* pNewList = pDataEntry->m_ProperityList->InsertBack( pDataEntry->m_ProperityList->m_Entry.Blink, pProperity); pDataEntry->m_ProperityList->m_Entry.Blink = &pNewList->m_Entry; pNewList->m_Entry.Blink = &pNewList->m_Entry; } } pEntry = pEntry->Flink; } } } CSysmonDataEntry* CSysmonMofData::GetPropertyList( IWbemClassObject* pClass, GUID* ClassGuid, USHORT Version, USHORT Level, USHORT Type) { CSysmonDataEntry* pDataEntry; CSysmonEventList* pEventList; CSysmonEventList* pEventList_2; CSysmonDataEntry* pRetEventv63; CSysmonDataEntry* pOldDataEntry; LONG Reference; BSTR bstrDisplayName; BSTR bstrClassName; BSTR bstrEventType; BSTR bstrEventTypeName; BSTR bstrWmiDataId; BSTR bstrVarClassName; VARIANT varClassName; VARIANT varDisplayName; VARIANTARG vargType; VARIANTARG vargTypeName; IWbemQualifierSet * pQualifierSet = NULL; IEnumWbemClassObject* pClasses = NULL; IWbemClassObject* pClass_1 = NULL; ULONG Cnt; HRESULT hr; ULONG* ppvData; BSTR* ppvData_2; OLECHAR szClassName[MAX_PATH] = {0}; OLECHAR szEventName[MAX_PATH] = {0}; pSafeArrayDestroy ApiSafeArrayDestroy = NULL; pSafeArrayGetElement ApiSafeArrayGetElement = NULL; pEventList = new CSysmonEventList(0,0); pDataEntry = NULL; VariantInit(&varClassName); VariantInit(&varDisplayName); VariantInit(&vargType); VariantInit(&vargTypeName); //VariantInit(&v40); //VariantInit(&v36); Reference = 1; pRetEventv63 = NULL; bstrClassName = SysAllocString(L"__CLASS"); bstrWmiDataId = SysAllocString(L"WmiDataId"); bstrEventType = SysAllocString(L"EventType"); bstrEventTypeName = SysAllocString(L"EventTypeName"); bstrDisplayName = SysAllocString(L"DisplayName"); if ( pClass->Get( bstrClassName, 0, &varClassName, 0, 0) == S_OK ) { StringCchCopy( szClassName, MAX_PATH, varClassName.bstrVal); if (pQualifierSet) { pQualifierSet->Release(); pQualifierSet = NULL; } pClass->GetQualifierSet(&pQualifierSet); if ( !pQualifierSet->Get( bstrDisplayName, 0, &varDisplayName, 0) && varDisplayName.lVal ) StringCchCopy(szClassName, MAX_PATH, varDisplayName.bstrVal); pDataEntry = new CSysmonDataEntry(ClassGuid,-1,-1,-1); pRetEventv63 = pDataEntry; pOldDataEntry = pDataEntry; if (pDataEntry) { pDataEntry->InitData(&pDataEntry->m_EventClassName,szClassName); pEventList_2 = pEventList->InsertBack( pEventList->m_Entry.Blink, pDataEntry); pEventList->m_Entry.Blink = &pEventList_2->m_Entry; pEventList_2->m_Entry.Blink->Flink = &pEventList_2->m_Entry; bstrVarClassName = SysAllocString(varClassName.bstrVal); hr = m_pIWbemService->CreateClassEnum( bstrVarClassName, WBEM_FLAG_DEEP | WBEM_FLAG_UPDATE_ONLY | WBEM_FLAG_USE_AMENDED_QUALIFIERS, 0, &pClasses); SysFreeString(bstrVarClassName); if ( hr == S_OK) { ApiSafeArrayDestroy = SafeArrayDestroy; ApiSafeArrayGetElement = SafeArrayGetElement; Cnt = 1; while ( TRUE ) { pClass_1 = 0; if ( pClasses->Next(5000, 1, &pClass_1, &Cnt) != S_OK ) { pClass_1 = pClass; pClass_1->AddRef(); } if ( pQualifierSet ) { pQualifierSet->Release(); pQualifierSet = 0; } pClass_1->GetQualifierSet(&pQualifierSet); VariantClear(&vargType); if ( pQualifierSet->Get( bstrEventType, 0, &vargType, 0) == S_OK ) { if (vargType.vt & VT_ARRAY) { SAFEARRAY* pl1 = vargType.parray; SAFEARRAY* pl2 = NULL; LONG plLbound_1 = 0; LONG plUbound_1 = 0; LONG plLbound_2 = 0; LONG plUbound_2 = 0; VariantClear(&vargTypeName); if ( pQualifierSet->Get( bstrEventTypeName, 0, &vargTypeName, 0) == S_OK && (vargTypeName.vt & VT_ARRAY) ) { pl2 = vargTypeName.parray; } if ( !pl1 || SafeArrayGetLBound(pl1, 1, &plLbound_1) || SafeArrayGetUBound(pl1, 1, &plUbound_1) || plUbound_1 < 0 ) { pDataEntry = pRetEventv63; break; } SafeArrayAccessData(pl1, (void**)&ppvData); if ( pl2 ) { if ( SafeArrayGetLBound(pl2, 1, &plLbound_2) || SafeArrayGetUBound(pl2, 1, &plUbound_2) || plUbound_2 < 0 ) { pDataEntry = pRetEventv63; break; } SafeArrayAccessData(pl2, (void**)&ppvData_2); } if ( plLbound_1 <= plUbound_1) { LONG rgIndices = plLbound_1; while(TRUE) { do { USHORT uType = (*(USHORT*)&ppvData[rgIndices]); try { CSysmonDataEntry* pDataEntry__3 = new CSysmonDataEntry(ClassGuid,uType,Version,Level); if (pDataEntry__3) { InsertBack(pEventList,&Reference,pDataEntry__3); if (pOldDataEntry->GetCLassNameLen()) { *pDataEntry__3 = pOldDataEntry; } if (Type == uType) { pRetEventv63 = pDataEntry__3; } if ( pl2 ) { if ( rgIndices < plLbound_2 || rgIndices > plUbound_2 ) { break; } pDataEntry__3->InitData( &pDataEntry__3->m_EventTypeName, ppvData_2[rgIndices]); } } } catch(...) { } } while (FALSE); rgIndices++; if ( rgIndices > plUbound_1 ) { pl1 = vargType.parray; break; } } } SafeArrayUnaccessData(pl1); ApiSafeArrayDestroy(pl1); VariantInit(&vargType); if ( pl2 ) { SafeArrayUnaccessData(pl2); SafeArrayDestroy(pl2); VariantInit(&vargTypeName); } } else { VariantChangeType(&vargType, &vargType, 0, VT_I2); USHORT vType = vargType.iVal; VariantClear(&vargTypeName); if ( pQualifierSet->Get( bstrEventTypeName, 0, &vargTypeName, 0) ) { szEventName[0] = 0; } else { wcscpy_s( szEventName, MAX_PATH, vargTypeName.bstrVal ); } CSysmonDataEntry* pDataEntry__3 = new CSysmonDataEntry(ClassGuid,vType,Version,Level); if (pDataEntry__3) { InsertBack(pEventList,&Reference,pDataEntry__3); if (pOldDataEntry->GetCLassNameLen()) { *pDataEntry__3 = pOldDataEntry; } if ( Type == vType) { pRetEventv63 = pDataEntry__3; } pDataEntry__3->InitData( &pDataEntry__3->m_EventTypeName, szEventName); } } } SAFEARRAY* pNames = NULL; LONG plLbound_1 = 0; LONG plUbound_1 = 0; LONG plLbound_2 = 0; LONG plUbound_2 = 0; BSTR pv_1 = NULL; CIMTYPE QualifierType = 0; VariantClear(&varClassName); varClassName.vt = VT_I4; varClassName.lVal = 1; //LONG Index = 1; //hr = pClass->GetNames(NULL, WBEM_FLAG_LOCAL_ONLY, NULL, &pNames); hr = pClass_1->GetNames( bstrWmiDataId, WBEM_FLAG_ONLY_IF_IDENTICAL, &varClassName, &pNames); while( hr == S_OK) { if ( SafeArrayGetLBound(pNames, 1, &plLbound_1) || SafeArrayGetUBound(pNames, 1, &plUbound_1) || plUbound_1 < 0 ) break; //plUbound_1 = pNames->rgsabound->cElements; if ( plLbound_1 <= plUbound_1 ) { LONG nIndex = plLbound_1; do { if ( ApiSafeArrayGetElement(pNames, &nIndex, &pv_1) || pClass_1->Get(pv_1, 0, 0, &QualifierType, 0) ) break; if ( pQualifierSet ) { pQualifierSet->Release(); pQualifierSet = 0; } if ( pClass_1->GetPropertyQualifierSet(pv_1, &pQualifierSet) ) break; LONG v30 = GetArrayValue(QualifierType, pQualifierSet); LONG ArraySize = QualifierType & 0x2000 ? GetArraySize(pQualifierSet) : 1; SysmonAddProperityList( pEventList, pv_1, v30, ArraySize); ++nIndex; } while ( nIndex <= plUbound_1 ); } ApiSafeArrayDestroy(pNames); pNames = 0; varClassName.lVal++;// = (Index++); } AddEvent(pEventList); if ( Cnt != 1 ) { pDataEntry = pRetEventv63; break; } }//1 }//0. } } VariantClear(&varClassName); VariantClear(&varDisplayName); VariantClear(&vargTypeName); SysFreeString(bstrClassName); SysFreeString(bstrDisplayName); SysFreeString(bstrEventType); SysFreeString(bstrEventTypeName); SysFreeString(bstrWmiDataId); AddEvent(pEventList); LIST_ENTRY* pEntry = pEventList->m_Entry.Flink; InitializeListHead(&pEventList->m_Entry); while (pEntry != &pEventList->m_Entry) { CSysmonEventList* pList = CONTAINING_RECORD( pEntry, CSysmonEventList,m_Entry); pEntry = pEntry->Flink; if (pList) { delete pList; pList = NULL; } } return pDataEntry; } CSysmonEventList* CSysmonMofData::AddEvent( CSysmonEventList* pEventList) { CSysmonEventList* pRetList = pEventList; if (pEventList) { LIST_ENTRY* pEntry = pEventList->m_Entry.Flink; while(pEntry != &pEventList->m_Entry ) { CSysmonEventList* pList = CONTAINING_RECORD(pEntry,CSysmonEventList,m_Entry); if (pList) { CSysmonDataEntry* pDataEntry = (CSysmonDataEntry*)pList->m_pEvent; CSysmonEventList* pEvent = m_SysmonEventList->InsertBack( m_SysmonEventList->m_Entry.Blink, pDataEntry); m_SysmonEventList->m_Entry.Blink = &pEvent->m_Entry; pEvent->m_Entry.Blink->Flink = &pEvent->m_Entry; m_EventListNums++; } pEntry = pEntry->Flink; } pEntry = pEventList->m_Entry.Flink; InitializeListHead(&pEventList->m_Entry); while (pEntry != &pEventList->m_Entry) { CSysmonEventList* pList = CONTAINING_RECORD( pEntry, CSysmonEventList,m_Entry); pRetList = pList; pEntry = pEntry->Flink; if (pList) { delete pList; pList = NULL; } } return pRetList; } return NULL; } LONG CSysmonMofData::GetArrayValue( CIMTYPE CimType, IWbemQualifierSet * pQualifierSet) { LONG RetValue = 29; BSTR bstrQualifier; VARIANT varQualifier; HRESULT hr; BOOL bPointer; OLECHAR szFormat[11]; OLECHAR szStringTermination[31]; OLECHAR szExtension[31]; bPointer = 0; szFormat[0] = 0; szStringTermination[0] = 0; szExtension[0] = 0; if (pQualifierSet) { bstrQualifier = SysAllocString(L"Format"); VariantInit(&varQualifier); hr = pQualifierSet->Get(bstrQualifier, 0, &varQualifier, 0); SysFreeString(bstrQualifier); if ( !hr && varQualifier.lVal ) StringCchCopy(szFormat, 10, varQualifier.bstrVal); bstrQualifier = SysAllocString(L"StringTermination"); VariantClear(&varQualifier); hr = pQualifierSet->Get(bstrQualifier, 0, &varQualifier, 0); SysFreeString(bstrQualifier); if ( !hr && varQualifier.lVal ) StringCchCopy(szStringTermination, 30, varQualifier.bstrVal); bstrQualifier = SysAllocString(L"Pointer"); VariantClear(&varQualifier); hr = pQualifierSet->Get(bstrQualifier, 0, &varQualifier, 0); SysFreeString(bstrQualifier); if ( hr == S_OK) { bPointer = 1; } bstrQualifier = SysAllocString(L"Extension"); VariantClear(&varQualifier); hr = pQualifierSet->Get(bstrQualifier, 0, &varQualifier, 0); SysFreeString(bstrQualifier); if ( !hr && varQualifier.lVal ) StringCchCopy(szExtension, 30, varQualifier.bstrVal); VariantClear(&varQualifier); switch ( CimType & (~CIM_FLAG_ARRAY) ) { case CIM_SINT16: RetValue = 4; break; case CIM_SINT32: RetValue = 6; break; case CIM_REAL32: RetValue = 11; break; case CIM_REAL64: RetValue = 12; break; case CIM_STRING: { if ( _wcsicmp(szStringTermination, L"NullTerminated") ) { if ( _wcsicmp(szStringTermination, L"Counted") ) { if ( _wcsicmp(szStringTermination, L"ReverseCounted") ) RetValue = _wcsicmp(szStringTermination, L"NotCounted") != 0 ? 13 : 23; else RetValue = 18 - (_wcsicmp(szFormat, L"w") != 0); } else { RetValue = 16 - (_wcsicmp(szFormat, L"w") != 0); } } else { RetValue = 14 - (_wcsicmp(szFormat, L"w") != 0); } } break; case CIM_BOOLEAN: RetValue = 26; break; case CIM_OBJECT: if ( !_wcsicmp(szExtension, L"Port") ) { RetValue = 21; } else { if ( !_wcsicmp(szExtension, L"IPAddr") ) { RetValue = 20; } else if ( _wcsicmp(szExtension, L"Sid") ) { if ( _wcsicmp(szExtension, L"Guid") ) { if ( !_wcsicmp(szExtension, L"SizeT") ) { RetValue = 6; } else { if ( _wcsicmp(szExtension, L"IPAddrV6") ) { if ( _wcsicmp(szExtension, L"IPAddrV4") ) { if ( !_wcsicmp(szExtension, L"WmiTime") ) RetValue = 28; } else { RetValue = 20; } } else { RetValue = 27; } } } else { RetValue = 25; } } else { RetValue = 19; } } break; case CIM_SINT8: RetValue = 3; if ( !_wcsicmp(szFormat, L"c") ) RetValue = 0; break; case CIM_UINT8: RetValue = 2; break; case CIM_UINT16: RetValue = 5; break; case CIM_UINT32: RetValue = 7; break; case CIM_SINT64: RetValue = 9; break; case CIM_UINT64: RetValue = 10; break; case CIM_CHAR16: RetValue = 1; break; } if (bPointer) { RetValue = 24; } } return RetValue; } LONG CSysmonMofData::GetArraySize( IWbemQualifierSet* pQualifierSet) { LONG ArraySize = 1; VARIANT varQualifier; HRESULT hr; if ( pQualifierSet ) { BSTR bstrMax = SysAllocString(L"MAX"); VariantInit(&varQualifier); hr = pQualifierSet->Get(bstrMax, 0, &varQualifier, 0); SysFreeString(bstrMax); if ( !hr && varQualifier.vt == 3 ) ArraySize = varQualifier.lVal; VariantClear(&varQualifier); } return ArraySize; } CSysmonData::CSysmonData() :m_pData(NULL) ,m_pAlloc(NULL) ,m_Reference(0) { } CSysmonData::~CSysmonData() { } BOOL CSysmonData::Compare(BSTR pString) { if (pString && m_pData) { return _wcsicmp(m_pData,pString) == 0; } return FALSE; } BOOL CSysmonData::CompareN(BSTR pString,ULONG Size) { if (pString && m_pData) { return _wcsnicmp(m_pData,pString,Size) == 0; } return FALSE; } CSysmonDataEntry::CSysmonDataEntry() :m_EventClassName(NULL) ,m_EventTypeName(NULL) ,m_ProperitySize(0) { } CSysmonDataEntry::CSysmonDataEntry( GUID* Guid, USHORT Type, USHORT Version, USHORT Level) { m_EventClassName = NULL; m_EventTypeName = NULL; m_EventType = Type; m_EventVersion = Version; m_EventLevel = Level; m_ProperitySize = 0; m_ProperityList = new CSysmonEventList(0,0); _mm_storeu_si128( (__m128i *)&m_EventGuid, _mm_loadu_si128((const __m128i *)Guid)); } CSysmonDataEntry::~CSysmonDataEntry() { } LONG CSysmonDataEntry::GetCLassNameLen() { if ( m_EventClassName && m_EventClassName->m_pData) { return SysStringLen(m_EventClassName->m_pData); } return 0; } CSysmonDataEntry* CSysmonDataEntry::InitData(CSysmonData** pData,BSTR pString) { BSTR pOldData = 0; if (pData && *pData) { pOldData = (*pData)->m_pData; } if (!pString || pOldData != pString) { if (*pData) { if ( !InterlockedDecrement((volatile LONG *)&(*pData)->m_Reference)) { if ((*pData)->m_pData) { SysFreeString((*pData)->m_pData); (*pData)->m_pData = 0; } if ( m_EventClassName->m_pAlloc ) { delete (*pData)->m_pAlloc; (*pData)->m_pAlloc = 0; } delete (*pData); } (*pData) = NULL; } } CSysmonData* pNew = new CSysmonData(); if (pNew) { pNew->m_pAlloc = 0; pNew->m_Reference = 1; pNew->m_pData = SysAllocString(pString); if ( !pNew->m_pData && pString ) { // LogError(0x8007000E); } } else { //LogError(0x8007000E); } *pData = pNew; return this; } CSysmonEventList::CSysmonEventList() :m_pEvent(0) { InitializeListHead(&m_Entry); } CSysmonEventList::CSysmonEventList( LIST_ENTRY* Fink, LIST_ENTRY* Blink) :m_pEvent(0) { LIST_ENTRY* pl1; LIST_ENTRY* pl2; pl1 = Fink; m_pEvent = 0; if (Fink) { pl2 = Blink; } else { pl1 = &m_Entry; pl2 = &m_Entry; } m_Entry.Flink = pl1; m_Entry.Blink = pl2; } CSysmonEventList::~CSysmonEventList() { } CSysmonEventList* CSysmonEventList::InsertBack(LIST_ENTRY* Blink,void* pElm) { CSysmonEventList* pList = new CSysmonEventList( &m_Entry, Blink); if (pList) { pList->m_pEvent = pElm; } return pList; } ================================================ FILE: Sysmon/CSysmonMofData.h ================================================ #ifndef _CSysmonMofData_h #define _CSysmonMofData_h #include "Sysmon.h" #include #include #include #include #include #include #include #include extern "C" { typedef HRESULT (WINAPI * pSafeArrayDestroy)(SAFEARRAY *); typedef HRESULT (WINAPI * pSafeArrayGetElement)(SAFEARRAY * , LONG *, void *); }; typedef struct _CTcpIpInfo { BSTR NetName; ULONG NetType; }CTcpIpInfo; typedef struct _Sysmon_Net_Report { ULONG NrSize; ULONG NrProcessId; ULONG NrThreadId; GUID NrGuid; LARGE_INTEGER NrSystemTime; ULONG NrEventType; ULONG NrUdpOrTcp; }Sysmon_Net_Report; class CSysmonData { friend class CSysmonDataEntry; friend class CSysmonProperty; friend class CSysmonMofData; public: CSysmonData(); ~CSysmonData(); BOOL Compare(BSTR pString); BOOL CompareN(BSTR pString,ULONG Size); LONG Len() { if (m_pData) { __try { return lstrlen(m_pData); } __except(EXCEPTION_EXECUTE_HANDLER) { } } return 0; } private: BSTR m_pData; void* m_pAlloc; LONG m_Reference; }; class CSysmonEventList { friend class CSysmonMofData; public: CSysmonEventList(); ~CSysmonEventList(); BOOL IsListEmpty() { return ::IsListEmpty(&m_Entry); } CSysmonEventList(LIST_ENTRY* Fink,LIST_ENTRY* Blink); CSysmonEventList* InsertBack(LIST_ENTRY* Blink,void* pElm); private: void* m_pEvent; public: LIST_ENTRY m_Entry; }; class CSysmonDataEntry { friend class CSysmonMofData; public: CSysmonDataEntry(); CSysmonDataEntry(GUID* Guid,USHORT Type,USHORT Version,USHORT Level); ~CSysmonDataEntry(); void operator =(CSysmonDataEntry* pDataEntry); CSysmonDataEntry* InitData(CSysmonData** pData,BSTR pString); LONG GetCLassNameLen(); private: CSysmonData* m_EventClassName; CSysmonData* m_EventTypeName; GUID m_EventGuid; USHORT m_EventType; USHORT m_EventVersion; USHORT m_EventLevel; ULONG m_ProperitySize; CSysmonEventList* m_ProperityList; }; class CSysmonProperty { friend class CSysmonMofData; public: CSysmonProperty() :m_Data(NULL) ,m_Len(0), m_ArraySize(0) { } CSysmonProperty(BSTR pName,LONG Len,LONG ArraySize) :m_Data(NULL) ,m_Len(0), m_ArraySize(0) { if (pName) { InitData(&m_Data,pName); } m_Len = Len; m_ArraySize = ArraySize; } ~CSysmonProperty() { } void InitData(CSysmonData** pData,BSTR pString) { BSTR pOldData = 0; if (pData && *pData) { pOldData = (*pData)->m_pData; } if (!pString || pOldData != pString) { if (*pData) { if ( !InterlockedDecrement((volatile LONG *)&(*pData)->m_Reference)) { if ((*pData)->m_pData) { SysFreeString((*pData)->m_pData); (*pData)->m_pData = 0; } if ( (*pData)->m_pAlloc ) { delete (*pData)->m_pAlloc; (*pData)->m_pAlloc = 0; } delete (*pData); } (*pData) = NULL; } } CSysmonData* pNew = new CSysmonData(); if (pNew) { pNew->m_pAlloc = 0; pNew->m_Reference = 1; pNew->m_pData = SysAllocString(pString); if ( !pNew->m_pData && pString ) { // LogError(0x8007000E); } } else { //LogError(0x8007000E); } *pData = pNew; } private: CSysmonData* m_Data; LONG m_Len; LONG m_ArraySize; }; class CSysmonMofData { public: CSysmonMofData(void); virtual ~CSysmonMofData(void); public: CSysmonDataEntry* GetEventCategoryClass( GUID* ClassGuid, USHORT Version, USHORT Level, USHORT Type); CSysmonDataEntry* GetPropertyList( IWbemClassObject* pClass, GUID* ClassGuid, USHORT Version, USHORT Level, USHORT Type); void SysmonAddProperityList( CSysmonEventList* pList, BSTR ProperityName, LONG Len, LONG ArraySize); CSysmonDataEntry* Phase_1( GUID* ClassGuid, USHORT Version, USHORT Level, USHORT Type); void Phase_2( PEVENT_TRACE pEvent, CSysmonDataEntry* pDataEntry ); HRESULT CoCreateInstance(); LONG GetArraySize(IWbemQualifierSet* pQualifierSet); LONG GetArrayValue( CIMTYPE CimType, IWbemQualifierSet * pQualifierSet); void InsertBack( CSysmonEventList* pEventList, LONG* Reference, void* pElm); CSysmonEventList* AddEvent(CSysmonEventList* pEventList); private: IWbemServices* m_pIWbemService; CSysmonEventList* m_SysmonEventList; LONG m_EventListNums; public: static CTcpIpInfo m_TcpIpEventTypeName[25]; }; #endif ================================================ FILE: Sysmon/CSysmonUtil.cpp ================================================ #include "StdAfx.h" #include "CSysmonUtil.h" CSysmonUtil::CSysmonUtil(void) { } CSysmonUtil::~CSysmonUtil(void) { } BOOL CSysmonUtil::SysmonVersionIsSupport() { BOOL result; OSVERSIONINFOEX VersionInformation; VersionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); VersionInformation.dwMajorVersion = 0; memset( &VersionInformation.dwMinorVersion, 0, sizeof(OSVERSIONINFOW)); GetVersionEx((POSVERSIONINFO)&VersionInformation); if ( VersionInformation.dwMajorVersion >= 6 ) return 1; if ( VersionInformation.dwMajorVersion != 5 || !VersionInformation.dwMinorVersion ) { result = 0; } if ( VersionInformation.dwMinorVersion == 1 ) { //= XP2 return VersionInformation.wServicePackMajor >= 2; } if ( VersionInformation.dwMinorVersion == 2 ) { result = (VersionInformation.wProductType == VER_NT_WORKSTATION); } else { result = 0; } return result; } unsigned __int64 CSysmonUtil::CounterTimes(FILETIME t1,__int64 t2) { unsigned __int64 Result = 0; if ( t2 >= 0 ) { return (unsigned __int64)(10000000 * (t2 % (QWORD)(t1.dwLowDateTime + 16))) / (QWORD)(t1.dwLowDateTime + 16) + 10000000 * (t2 / (QWORD)(t1.dwLowDateTime + 16)); } else { Result = CounterTimes(t1,-t2); } return Result; } ================================================ FILE: Sysmon/CSysmonUtil.h ================================================ #ifndef _CSysmonUtil_h #define _CSysmonUtil_h typedef unsigned __int64 QWORD; class CSysmonUtil { public: CSysmonUtil(void); ~CSysmonUtil(void); public: static BOOL SysmonVersionIsSupport(); static unsigned __int64 CounterTimes(FILETIME t1,__int64 t2); }; #endif ================================================ FILE: Sysmon/ReadMe.txt ================================================ ======================================================================== WIN32 APPLICATION : Sysmon Project Overview ======================================================================== AppWizard has created this Sysmon application for you. This file contains a summary of what you will find in each of the files that make up your Sysmon application. Sysmon.vcxproj This is the main project file for VC++ projects generated using an Application Wizard. It contains information about the version of Visual C++ that generated the file, and information about the platforms, configurations, and project features selected with the Application Wizard. Sysmon.vcxproj.filters This is the filters file for VC++ projects generated using an Application Wizard. It contains information about the association between the files in your project and the filters. This association is used in the IDE to show grouping of files with similar extensions under a specific node (for e.g. ".cpp" files are associated with the "Source Files" filter). Sysmon.cpp This is the main application source file. ///////////////////////////////////////////////////////////////////////////// AppWizard has created the following resources: Sysmon.rc This is a listing of all of the Microsoft Windows resources that the program uses. It includes the icons, bitmaps, and cursors that are stored in the RES subdirectory. This file can be directly edited in Microsoft Visual C++. Resource.h This is the standard header file, which defines new resource IDs. Microsoft Visual C++ reads and updates this file. Sysmon.ico This is an icon file, which is used as the application's icon (32x32). This icon is included by the main resource file Sysmon.rc. small.ico This is an icon file, which contains a smaller version (16x16) of the application's icon. This icon is included by the main resource file Sysmon.rc. ///////////////////////////////////////////////////////////////////////////// Other standard files: StdAfx.h, StdAfx.cpp These files are used to build a precompiled header (PCH) file named Sysmon.pch and a precompiled types file named StdAfx.obj. ///////////////////////////////////////////////////////////////////////////// Other notes: AppWizard uses "TODO:" comments to indicate parts of the source code you should add to or customize. ///////////////////////////////////////////////////////////////////////////// ================================================ FILE: Sysmon/Resource.h ================================================ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by Sysmon.rc // #define IDS_APP_TITLE 103 #define IDR_MAINFRAME 128 #define IDD_SYSMON_DIALOG 102 #define IDD_ABOUTBOX 103 #define IDM_ABOUT 104 #define IDM_EXIT 105 #define IDI_SYSMON 107 #define IDI_SMALL 108 #define IDC_SYSMON 109 #define IDC_MYICON 2 #ifndef IDC_STATIC #define IDC_STATIC -1 #endif // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NO_MFC 130 #define _APS_NEXT_RESOURCE_VALUE 129 #define _APS_NEXT_COMMAND_VALUE 32771 #define _APS_NEXT_CONTROL_VALUE 1000 #define _APS_NEXT_SYMED_VALUE 110 #endif #endif ================================================ FILE: Sysmon/Sysmon.cpp ================================================ // Sysmon.cpp : Defines the entry point for the application. // #include "stdafx.h" #include "Sysmon.h" #include #include "CSysmonDriverOpt.h" #include "CSsymonEtw.h" #include #include #include #define MAX_LOADSTRING 100 extern "C" typedef BOOL (WINAPI *pIsWow64Process)( HANDLE hProcess, PBOOL Wow64Process ); int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); int argc = 0; char** argv = NULL; WCHAR** argvW = (WCHAR**)NULL; argvW = ::CommandLineToArgvW(::GetCommandLine(), &argc); // argv = (char**)malloc(argc * sizeof(char*)); // int cb = 0; // for (int i = 0; i < argc; i++) // { // cb = WideCharToMultiByte (CP_ACP, 0, argvW[i], -1, NULL, 0, NULL, NULL); // argv[i] = (char*)malloc(cb * sizeof(WCHAR) + 1); // WideCharToMultiByte (CP_ACP, 0, argvW[i], -1, argv[i], cb, NULL, NULL); // } BOOL bIsWow64Process = FALSE; HMODULE v4 = GetModuleHandleW(L"kernel32.dll"); pIsWow64Process v5 = (pIsWow64Process)GetProcAddress(v4, "IsWow64Process"); if ( v5 ) { v5(GetCurrentProcess(), &bIsWow64Process); } if (bIsWow64Process) { return RunSysmonX64(); } if (argc > 1) { if (lstrcmpi(argvW[1],_T("-i")) == 0 ) { CSysmonDriverOpt Opt; Opt.InstallDriver( _T("Sysmon"), _T("Sysmon.sys"), _T("370030")); if(Opt.StartDriver(_T("Sysmon"))) { MessageBox(NULL,_T("Success"),_T("Success"),MB_OK); } } if (lstrcmpi(argvW[1],_T("-n")) == 0 ) { CSsymonEtw::Instance()->StartTrace(1); } } MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; return TRUE; } extern "C" typedef void (WINAPI *pGetNativeSystemInfo)(LPSYSTEM_INFO lpSystemInfo); BOOLEAN __fastcall SysmonTempFileName(wchar_t * FileName, wchar_t* TempName) { wchar_t *v2; int i; unsigned int v5; wchar_t Dsta[MAX_PATH] = {0}; WCHAR Buffer[MAX_PATH] = {0}; WCHAR RandName[20] = {0}; v2 = TempName; wcscpy_s(Dsta, MAX_PATH, FileName); if ( !GetTempPathW(MAX_PATH, Buffer) ) return 0; i = 0; while ( TRUE ) { do { wcscpy_s(v2, 520, Buffer); if ( RandName[0] ) { wcscat_s(v2, 520, RandName); wcscat_s(v2, 520, L"\\"); if ( GetFileAttributesW(v2) != -1 || !CreateDirectoryW(v2, 0) ) break; } wcscat_s(v2, 520, Dsta); if ( GetFileAttributesW(v2) == -1 ) return 1; if ( RandName[0] ) { wcsrchr(v2, '\\')[1] = 0; RemoveDirectoryW(v2); } } while (FALSE); rand_s(&v5); swprintf_s(RandName, 20, L"SYS%u", v5); if ( (unsigned int)++i >= 10 ) return 0; } return 1; } wchar_t *__fastcall SysmonFormatMessageW(wchar_t *Dest, int len) { int v2; wchar_t *v3; DWORD v5; WCHAR* Buffer; Buffer = 0; v3 = Dest; v5 = FormatMessageW(12544, 0, GetLastError(), 0, (LPWSTR)&Buffer, 0, 0); if ( v5 && len >= (signed int)(v5 + 14) ) { Buffer[lstrlenW(Buffer) - 2] = 0; _swprintf(v3, L"%s", Buffer, GetLastError()); } else { *v3 = 0; } if ( Buffer ) LocalFree(*(HLOCAL *)Buffer); return v3; } BOOLEAN __fastcall SysmonExtractResource(LPCWSTR lpName, wchar_t *Filename) { HRSRC hrFile; HGLOBAL hgFile; DWORD nFileLength; const void *ptr; FILE *hFile; hrFile = FindResourceW(0, lpName, L"BINRES"); if ( !hrFile ) return 0; hgFile = LoadResource(0, hrFile); nFileLength = SizeofResource(0, hrFile); ptr = LockResource(hgFile); hFile = _wfopen(Filename, L"wb"); if ( !hFile ) return 0; fwrite(ptr, 1, nFileLength, hFile); fclose(hFile); return 1; } DWORD RunSysmonX64() { HMODULE v0; pGetNativeSystemInfo v1; DWORD result; wchar_t *v4; STARTUPINFOW StartupInfo = {0}; SYSTEM_INFO SystemInfo = {0}; PROCESS_INFORMATION ProcessInformation = {0}; DWORD ExitCode; wchar_t Dest[256] = {0}; WCHAR Filename[520] = {0}; ExitCode = 0; StartupInfo.cb = 68; StartupInfo.lpReserved = 0; memset(&StartupInfo.lpDesktop, 0, 0x3Cu); __m128i Xmm0 = {0}; _mm_storeu_si128((__m128i *)&ProcessInformation, Xmm0); v0 = LoadLibraryW(L"kernel32.dll"); v1 = (pGetNativeSystemInfo)GetProcAddress(v0, "GetNativeSystemInfo"); if ( v1 ) v1(&SystemInfo); else GetSystemInfo(&SystemInfo); if ( SystemInfo.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_AMD64 ) { wprintf(L"Unsupported processor type: %d\n", SystemInfo.wProcessorArchitecture); return 1630; } memset(Filename, 0, sizeof(WCHAR)*520); if ( !GetModuleFileNameW(0, Filename, 520) ) { ExitCode = GetLastError(); wprintf(L"Failed to get the module filename:\n%s\n\n", SysmonFormatMessageW(Dest, 256)); return ExitCode; } v4 = wcsrchr(Filename, '\\'); if ( !SysmonTempFileName(v4 + 1,Filename) ) { ExitCode = GetLastError(); wprintf(L"Failed to create temporaryfile:\n%s\n\n", SysmonFormatMessageW(Dest, 256)); return ExitCode; } if ( !SysmonExtractResource((LPCWSTR)1001,Filename) && GetFileAttributesW(Filename) == -1 ) { ExitCode = GetLastError(); wprintf(L"Failed to extract the 64-bit version:\n%s\n\n", SysmonFormatMessageW(Dest, 256)); return ExitCode; } if ( CreateProcessW( Filename, GetCommandLineW(), 0, 0, 0, 0, 0, 0, &StartupInfo, &ProcessInformation) ) { WaitForSingleObject(ProcessInformation.hProcess, 0xFFFFFFFF); GetExitCodeProcess(ProcessInformation.hProcess, &ExitCode); CloseHandle(ProcessInformation.hProcess); CloseHandle(ProcessInformation.hThread); result = ExitCode; if ( ExitCode == 999 ) return result; } else { ExitCode = GetLastError(); wprintf(L"Error launching 64-bit version:\n%s\n\n", SysmonFormatMessageW(Dest, 256)); } DeleteFileW(Filename); return ExitCode; } ================================================ FILE: Sysmon/Sysmon.h ================================================ #pragma once #include "resource.h" BOOLEAN FORCEINLINE IsListEmpty( __in const LIST_ENTRY * ListHead ) { return (BOOLEAN)(ListHead->Flink == ListHead); } FORCEINLINE VOID InitializeListHead( __out PLIST_ENTRY ListHead ) { ListHead->Flink = ListHead->Blink = ListHead; } FORCEINLINE VOID InsertTailList( __inout PLIST_ENTRY ListHead, __inout __drv_aliasesMem PLIST_ENTRY Entry ) { PLIST_ENTRY Blink; Blink = ListHead->Blink; Entry->Flink = ListHead; Entry->Blink = Blink; Blink->Flink = Entry; ListHead->Blink = Entry; } FORCEINLINE BOOLEAN RemoveEntryList( __in PLIST_ENTRY Entry ) { PLIST_ENTRY Blink; PLIST_ENTRY Flink; Flink = Entry->Flink; Blink = Entry->Blink; Blink->Flink = Flink; Flink->Blink = Blink; return (BOOLEAN)(Flink == Blink); } FORCEINLINE PLIST_ENTRY RemoveHeadList( __inout PLIST_ENTRY ListHead ) { PLIST_ENTRY Flink; PLIST_ENTRY Entry; Entry = ListHead->Flink; Flink = Entry->Flink; ListHead->Flink = Flink; Flink->Blink = ListHead; return Entry; } DWORD RunSysmonX64(); ================================================ FILE: Sysmon/Sysmon.vcxproj ================================================  Debug Win32 Debug x64 Release Win32 Release x64 {E64CC626-B5DB-47C9-93DD-D14F2F60B6C6} Win32Proj Sysmon Application true Unicode Static Application true Unicode Application false true Unicode Application false true Unicode true true false false $(ProjectName)64 Use Level3 Disabled WIN32;_DEBUG;_WINDOWS;INITGUID;%(PreprocessorDefinitions) MultiThreadedDebug Async Windows true Use Level3 Disabled WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) Windows true Level3 Use MaxSpeed true true WIN32;NDEBUG;_WINDOWS;INITGUID;%(PreprocessorDefinitions) MultiThreaded Windows true true true Level3 Use MaxSpeed true true WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) Windows true true true Create Create Create Create ================================================ FILE: Sysmon/Sysmon.vcxproj.filters ================================================  {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Resource Files Resource Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Resource Files Source Files ================================================ FILE: Sysmon/Sysmon.vcxproj.user ================================================  -n WindowsLocalDebugger sysmon.exe -i WindowsLocalDebugger ================================================ FILE: Sysmon/stdafx.cpp ================================================ // stdafx.cpp : source file that includes just the standard includes // Sysmon.pch will be the pre-compiled header // stdafx.obj will contain the pre-compiled type information #include "stdafx.h" // TODO: reference any additional headers you need in STDAFX.H // and not in this file ================================================ FILE: Sysmon/stdafx.h ================================================ // stdafx.h : include file for standard system include files, // or project specific include files that are used frequently, but // are changed infrequently // #pragma once #include "targetver.h" #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers // Windows Header Files: #include // C RunTime Header Files #include #include #include #include // TODO: reference additional headers your program requires here ================================================ FILE: Sysmon/targetver.h ================================================ #pragma once // Including SDKDDKVer.h defines the highest available Windows platform. // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. #define _CRT_RAND_S #include ================================================ FILE: Sysmon/undname.cpp ================================================ // // Copyright (c) Microsoft Corporation. All rights reserved. // // // This source code is licensed under Microsoft Shared Source License // Version 1.0 for Windows CE. // For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223. // // Make sure all dependent defines exist and have a valid value #include "stdafx.h" // #ifndef NO_COMPILER_NAMES // #define NO_COMPILER_NAMES 0 // #endif // #ifndef VERS_32BIT // #define VERS_32BIT 1 // #endif // #ifndef PACK_SIZE // #if !VERS_32BIT // #define PACK_SIZE 2 // #elif defined(_X86_) // #define PACK_SIZE 4 // #else // #define PACK_SIZE 8 // #endif // #endif // // Check for version inconsistancies, and setup version flags // #ifdef VERS_BSC // #undef NO_COMPILER_NAMES // #define NO_COMPILER_NAMES 1 // #pragma inline_depth ( 3 ) // #pragma check_stack ( off ) // #else // #pragma inline_depth ( 3 ) // #pragma check_stack ( off ) // #endif // #define PURE =0 // // #include // #include // #include "undname.h" // #pragma warning(disable:4291) // No matching operator delete // class DName; // class DNameNode; // class Replicator; // class HeapManager; // class UnDecorator; // const unsigned int memBlockSize = 508; // A '512' byte block including the header // class HeapManager // { // private: // Alloc_t pOpNew; // Free_t pOpDelete; // struct Block // { // Block * next; // char memBlock[ memBlockSize ]; // __near Block () { next = 0; } // }; // Block * head; // Block * tail; // unsigned int blockLeft; // public: // void __near Constructor ( Alloc_t pAlloc, Free_t pFree ) // { pOpNew = pAlloc; // pOpDelete = pFree; // blockLeft = 0; // head = 0; // tail = 0; // } // void __far * __near getMemory ( unsigned int, int ); // void __near Destructor ( void ) // { if ( pOpDelete != 0 ) // while ( tail = head ) // { // head = tail->next; // ( *pOpDelete )( tail ); // } // } // #define gnew new(heap,0) // #define rnew new(heap,1) // }; // void * __near __pascal operator new ( unsigned int, HeapManager &, int = 0 ); // static HeapManager heap; // // The MS Token table // enum Tokens // { // #if !VERS_32BIT // TOK_near, // TOK_nearSp, // TOK_nearP, // TOK_far, // TOK_farSp, // TOK_farP, // TOK_huge, // TOK_hugeSp, // TOK_hugeP, // #endif // TOK_basedLp, // TOK_cdecl, // TOK_pascal, // TOK_stdcall, // TOK_thiscall, // TOK_fastcall, // TOK_cocall, // TOK_ptr64, // TOK_restrict, // #if !VERS_32BIT // TOK_interrupt, // TOK_saveregs, // TOK_self, // TOK_segment, // TOK_segnameLpQ, // #endif // TOK__last // }; // static const pcchar_t __near tokenTable[] = // { // #if !VERS_32BIT // "__near", // TOK_near // "__near ", // TOK_nearSp // "__near*", // TOK_nearP // "__far", // TOK_far // "__far ", // TOK_farSp // "__far*", // TOK_farP // "__huge", // TOK_huge // "__huge ", // TOK_hugeSp // "__huge*", // TOK_hugeP // #endif // "__based(", // TOK_basedLp // "__cdecl", // TOK_cdecl // "__pascal", // TOK_pascal // "__stdcall", // TOK_stdcall // "__thiscall", // TOK_thiscall // "__fastcall", // TOK_fastcall // "__cocall", // TOK_cocall // "__ptr64", // TOK_ptr64 // "__restrict", // TOK_restrict // #if !VERS_32BIT // "__interrupt", // TOK_interrupt // "__saveregs", // TOK_saveregs // "__self", // TOK_self // "__segment", // TOK_segment // "__segname("", // TOK_segnameLpQ // #endif // "" // }; // // The operator mapping table // static const pcchar_t __near nameTable[] = // { // " new", // " delete", // "=", // ">>", // "<<", // "!", // "==", // "!=", // "[]", // "operator", // "->", // "*", // "++", // "--", // "-", // "+", // "&", // "->*", // "/", // "%", // "<", // "<=", // ">", // ">=", // ",", // "()", // "~", // "^", // "|", // "&&", // "||", // "*=", // "+=", // "-=", // "/=", // "%=", // ">>=", // "<<=", // "&=", // "|=", // "^=", // #if ( !NO_COMPILER_NAMES ) // "`vftable'", // "`vbtable'", // "`vcall'", // "`typeof'", // "`local static guard'", // "`string'", // "`vbase destructor'", // "`vector deleting destructor'", // "`default constructor closure'", // "`scalar deleting destructor'", // "`vector constructor iterator'", // "`vector destructor iterator'", // "`vector vbase constructor iterator'", // "`virtual displacement map", // "`eh vector constructor iterator'", // "`eh vector destructor iterator'", // "`eh vector vbase constructor iterator'", // "`copy constructor closure'", // "`udt returning'", // "`EH", //eh initialized struct // "`RTTI", //rtti initialized struct // "`local vftable'", // "`local vftable constructor closure'", // #endif // !NO_COMPILER_NAMES // " new[]", // " delete[]", // #if ( !NO_COMPILER_NAMES ) // "`omni callsig'", // "`placement delete closure'", // "`placement delete[] closure'", // #endif // "" // }; // static const pcchar_t __near ehTable[] = // { // " Ptr to Member Data'", // " Catchable Type'", // " Catchable Type Array'", // " ThrowInfo'", // }; // static const pcchar_t __near rttiTable[] = // { // " Type Descriptor'", // " Base Class Descriptor at (", // " Base Class Array'", // " Class Hierarchy Descriptor'", // " Complete Object Locator'", // }; // // The following 'enum' should really be nested inside 'class DName', but to // // make the code compile better with Glockenspiel, I have extracted it // enum DNameStatus // { // DN_valid, // DN_invalid, // DN_truncated, // DN_error // }; // class DName // { // public: // __near DName (); // __near DName ( char ); // #if 1 // __near DName ( const DName & ); // Shallow copy // #endif // __near DName ( DNameNode * ); // __near DName ( pcchar_t ); // __near DName ( pcchar_t&, char ); // __near DName ( DNameStatus ); // __near DName ( DName * ); // __near DName ( unsigned long ); // int __near isValid () const; // int __near isEmpty () const; // DNameStatus __near status () const; // DName & __near setPtrRef (); // int __near isPtrRef () const; // int __near isUDC () const; // void __near setIsUDC (); // int __near isUDTThunk () const; // void __near setIsUDTThunk (); // int isNoTE () const; // void setIsNoTE (); // int __near length () const; // char __near getLastChar () const; // pchar_t __near getString ( pchar_t, int ) const; // DName __near operator + ( pcchar_t ) const; // DName __near operator + ( const DName & ) const; // DName __near operator + ( char ) const; // DName __near operator + ( DName * ) const; // DName __near operator + ( DNameStatus ) const; // DName & __near operator += ( char ); // DName & __near operator += ( pcchar_t ); // DName & __near operator += ( DName * ); // DName & __near operator += ( DNameStatus ); // DName & __near operator += ( const DName & ); // DName & __near operator |= ( const DName & ); // DName & __near operator = ( pcchar_t ); // DName & __near operator = ( const DName & ); // DName & __near operator = ( char ); // DName & __near operator = ( DName * ); // DName & __near operator = ( DNameStatus ); // // Friends : // friend DName __near __pascal operator + ( char, const DName & ); // friend DName __near __pascal operator + ( pcchar_t, const DName & ); // friend DName __near __pascal operator + ( DNameStatus, const DName & ); // private: // DNameNode * node; // DNameStatus stat : 4; // unsigned int isIndir : 1; // unsigned int isAUDC : 1; // unsigned int isAUDTThunk : 1; // unsigned int NoTE : 1; // void __near doPchar ( pcchar_t, int ); // }; // class Replicator // { // private: // // Declare, in order to suppress automatic generation // void operator = ( const Replicator& ); // int index; // DName * dNameBuffer[ 10 ]; // const DName ErrorDName; // const DName InvalidDName; // public: // __near Replicator (); // int __near isFull () const; // Replicator & __near operator += ( const DName & ); // const DName & __near operator [] ( int ) const; // }; // class UnDecorator // { // private: // // Declare, in order to suppress automatic generation // void operator = ( const UnDecorator& ); // Replicator ArgList; // static Replicator * pArgList; // Replicator ZNameList; // static Replicator * pZNameList; // static Replicator * pTemplateArgList; // static pcchar_t gName; // static pcchar_t name; // static pchar_t outputString; // static int maxStringLength; // static unsigned long disableFlags; // static DName __near getDecoratedName ( void ); // static DName __near getSymbolName ( void ); // static DName __near getZName ( void ); // static DName __near getOperatorName ( void ); // static DName __near getScope ( void ); // static DName getScopedName ( void ); // static DName __near getSignedDimension ( void ); // static DName __near getDimension ( void ); // static int __near getNumberOfDimensions ( void ); // static DName __near getTemplateName ( void ); // static DName __near getTemplateArgumentList( void ); // static DName __near getTemplateConstant( void ); // static DName __near composeDeclaration ( const DName & ); // static int __near getTypeEncoding ( void ); // static DName __near getBasedType ( void ); // static DName __near getECSUName ( void ); // static DName __near getEnumType ( void ); // static DName __near getCallingConvention ( void ); // static DName __near getReturnType ( DName * = 0 ); // static DName __near getDataType ( DName * ); // static DName __near getPrimaryDataType ( const DName & ); // static DName __near getDataIndirectType ( const DName &, char, const DName &, int = FALSE ); // static DName __near getDataIndirectType (); // static DName __near getBasicDataType ( const DName & ); // static DName __near getECSUDataType ( void ); // static DName __near getPtrRefType ( const DName &, const DName &, int ); // static DName __near getPtrRefDataType ( const DName &, int ); // static DName __near getArrayType ( const DName& ); // static DName getFunctionIndirectType( const DName & superType ); // static DName __near getArgumentTypes ( void ); // static DName __near getArgumentList ( void ); // static DName __near getThrowTypes ( void ); // static DName __near getLexicalFrame ( void ); // static DName __near getStorageConvention ( void ); // static DName __near getThisType ( void ); // static DName __near getPointerType ( const DName &, const DName & ); // static DName __near getReferenceType ( const DName &, const DName & ); // static DName __near getExternalDataType ( const DName & ); // static DName __near getSegmentName ( void ); // #if ( !NO_COMPILER_NAMES ) // static DName __near getDisplacement ( void ); // static DName __near getCallIndex ( void ); // static DName __near getGuardNumber ( void ); // static DName __near getVfTableType ( const DName & ); // static DName __near getVbTableType ( const DName & ); // static DName __near getVCallThunkType ( void ); // #endif // !NO_COMPILER_NAMES // static DName getStringEncoding ( char *prefix, int wantBody ); // static GetParameter_t m_pGetParameter; // public: // __near UnDecorator ( pchar_t, pcchar_t, int, GetParameter_t, unsigned long ); // static int __near doUnderScore (); // static int __near doMSKeywords (); // static int __near doFunctionReturns (); // static int __near doAllocationModel (); // static int __near doAllocationLanguage (); // #if 0 // static int __near doMSThisType (); // static int __near doCVThisType (); // #endif // static int __near doThisTypes (); // static int __near doAccessSpecifiers (); // static int __near doThrowTypes (); // static int __near doMemberTypes (); // static int __near doReturnUDTModel (); // static int __near do32BitNear (); // static int __near doNameOnly (); // static int __near doTypeOnly (); // static int __near haveTemplateParameters (); // static int __near doEcsu (); // static int __near doNoIdentCharCheck (); // static pcchar_t __near UScore ( Tokens ); // __near operator pchar_t (); // }; // Replicator * UnDecorator::pArgList; // Replicator * UnDecorator::pZNameList = 0; // Replicator * UnDecorator::pTemplateArgList = 0; // pcchar_t UnDecorator::gName = 0; // pcchar_t UnDecorator::name = 0; // pchar_t UnDecorator::outputString = 0; // int UnDecorator::maxStringLength = 0; // unsigned long UnDecorator::disableFlags = 0; // GetParameter_t UnDecorator::m_pGetParameter = 0; // // #ifdef _CRTBLD // pchar_t __far _CRTIMP __loadds __unDName ( pchar_t outputString, // // #else // // pchar_t __far __cdecl __loadds unDName ( pchar_t outputString, // // #endif // pcchar_t name, // int maxStringLength, // Note, COMMA is leading following optional arguments // Alloc_t pAlloc, // Free_t pFree, // unsigned short disableFlags // ) // /* // * This function will undecorate a name, returning the string corresponding to // * the C++ declaration needed to produce the name. Its has a similar interface // * to 'strncpy'. // * // * If the target string 'outputString' is specified to be NULL, a string of // * suitable length will be allocated and its address returned. If the returned // * string is allocated by 'unDName', then it is the programmers responsibility // * to deallocate it. It will have been allocated on the far heap. // * // * If the target string is not NULL, then the parameter 'maxStringLength' will // * specify the maximum number of characters which may be placed in the string. // * In this case, the returned value is the same as 'outputString'. // * // * Both the input parameter 'name' and the returned string are NULL terminated // * strings of characters. // * // * If the returned value is NULL, it indicates that the undecorator ran out of // * memory, or an internal error occurred, and was unable to complete its task. // */ // { // // Must have an allocator and a deallocator (and we MUST trust them) // if ( !( pAlloc )) // return 0; // else // heap.Constructor ( pAlloc, pFree ); // // Create the undecorator object, and get the result // UnDecorator unDecorate ( outputString, // name, // maxStringLength, // 0, // disableFlags // ); // pchar_t unDecoratedName = unDecorate; // // Destruct the heap (would use a destructor, but that causes DLL problems) // heap.Destructor (); // // And return the composed name // return unDecoratedName; // } // End of FUNCTION "unDName" // // #ifdef _CRTBLD // pchar_t __far _CRTIMP __loadds __unDNameEx ( pchar_t outputString, // // #else // // pchar_t __far __cdecl __loadds unDNameEx ( pchar_t outputString, // // #endif // pcchar_t name, // int maxStringLength, // Note, COMMA is leading following optional arguments // Alloc_t pAlloc, // Free_t pFree, // GetParameter_t pGetParameter, // unsigned long disableFlags // ) // /* // * This function will undecorate a name, returning the string corresponding to // * the C++ declaration needed to produce the name. Its has a similar interface // * to 'strncpy'. // * // * If the target string 'outputString' is specified to be NULL, a string of // * suitable length will be allocated and its address returned. If the returned // * string is allocated by 'unDName', then it is the programmers responsibility // * to deallocate it. It will have been allocated on the far heap. // * // * If the target string is not NULL, then the parameter 'maxStringLength' will // * specify the maximum number of characters which may be placed in the string. // * In this case, the returned value is the same as 'outputString'. // * // * Both the input parameter 'name' and the returned string are NULL terminated // * strings of characters. // * // * If the returned value is NULL, it indicates that the undecorator ran out of // * memory, or an internal error occurred, and was unable to complete its task. // */ // { // // Must have an allocator and a deallocator (and we MUST trust them) // if ( !( pAlloc )) // return 0; // else // heap.Constructor ( pAlloc, pFree ); // // Create the undecorator object, and get the result // UnDecorator unDecorate ( outputString, // name, // maxStringLength, // pGetParameter, // disableFlags // ); // pchar_t unDecoratedName = unDecorate; // // Destruct the heap (would use a destructor, but that causes DLL problems) // heap.Destructor (); // // And return the composed name // return unDecoratedName; // } // End of FUNCTION "unDName" // // The 'UnDecorator' member functions // inline __near UnDecorator::UnDecorator ( pchar_t output, // pcchar_t dName, // int maxLen, // GetParameter_t pGetParameter, // unsigned long disable // ) // { // name = dName; // gName = name; // if ( output ) { // maxStringLength = maxLen - 1; // The algorithm in getString doesn't leave room // // for terminating NULL; be paranoid and leave one // // extra char. // // It's a lot easier to fix this here.... // outputString = output; // } // else { // outputString = 0; // maxStringLength = 0; // } // pZNameList = &ZNameList; // pArgList = &ArgList; // disableFlags = disable; // m_pGetParameter = pGetParameter; // } // End of "UnDecorator" CONSTRUCTOR '()' // inline __near UnDecorator::operator pchar_t () // { // DName result; // DName unDName; // // Find out if the name is a decorated name or not. Could be a reserved // // CodeView variant of a decorated name // if ( name ) // { // if (( *name == '?' ) && ( name[ 1 ] == '@' )) // { // #if ( !NO_COMPILER_NAMES ) // gName += 2; // result = "CV: " + getDecoratedName (); // #else // } elif NO_COMPILER_NAMES // result = DN_invalid; // #endif // NO_COMPILER_NAMES // } // End of IF then // elif (( *name == '?' ) && ( name[1] == '$' )) // result = getTemplateName (); // else // result = getDecoratedName (); // } // End of IF then // // If the name was not a valid name, then make the name the same as the original // // It is also invalid if there are any remaining characters in the name (except when // // we're giving the name only) // if ( result.status () == DN_error ) // return 0; // elif ( (*gName && !doNameOnly ()) || ( result.status () == DN_invalid )) // unDName = name; // Return the original name // else // unDName = result; // // Construct the return string // if ( !outputString ) // { // maxStringLength = unDName.length () + 1; // outputString = rnew char[ maxStringLength ]; // } // End of IF // if ( outputString ) // unDName.getString ( outputString, maxStringLength ); // // Return the result // return outputString; // } // End of "UnDecorator" OPERATOR 'pchar_t' // DName __near UnDecorator::getDecoratedName ( void ) // { // // Ensure that it is intended to be a decorated name // if ( doTypeOnly() ) // { // // Disable the type-only flag, so that if we get here recursively, eg. // // in a template tag, we do full name undecoration. // disableFlags &= ~UNDNAME_TYPE_ONLY; // // If we're decoding just a type, process it as the type for an abstract // // declarator, by giving an empty symbol name. // DName result = getDataType ( NULL ); // disableFlags |= UNDNAME_TYPE_ONLY; // return result; // } // elif ( *gName == '?' ) // { // // Extract the basic symbol name // gName++; // Advance the original name pointer // DName symbolName = getSymbolName (); // int udcSeen = symbolName.isUDC (); // // Abort if the symbol name is invalid // if ( !symbolName.isValid ()) // return symbolName; // // Extract, and prefix the scope qualifiers // if ( *gName && ( *gName != '@' )) { // DName scope = getScope (); // if ( !scope.isEmpty() ) // symbolName = scope + "::" + symbolName; // } // if ( udcSeen ) // symbolName.setIsUDC (); // // Now compose declaration // if ( symbolName.isEmpty () || symbolName.isNoTE() ) // { // return symbolName; // } // elif ( !*gName || ( *gName == '@' ) ) // { // if ( *gName ) // gName++; // if (doNameOnly () && !udcSeen) { // // Eat the rest of the dname, in case this is a recursive invocation, // // such as for a template argument. // (void)composeDeclaration( DName() ); // return symbolName; // } // else { // return composeDeclaration ( symbolName ); // } // } // End of ELIF then // else // return DN_invalid; // } // End of IF then // elif ( *gName ) // return DN_invalid; // else // return DN_truncated; // } // End of "UnDecorator" FUNCTION "getDecoratedName" // inline DName __near UnDecorator::getSymbolName ( void ) // { // if ( *gName == '?' ) // { // gName++; // return getOperatorName (); // } // End of IF then // else // return getZName (); // } // End of "UnDecorator" FUNCTION "getSymbolName" // DName __near UnDecorator::getZName ( void ) // { // int zNameIndex = *gName - '0'; // // Handle 'zname-replicators', otherwise an actual name // if (( zNameIndex >= 0 ) && ( zNameIndex <= 9 )) // { // gName++; // Skip past the replicator // // And return the indexed name // return ( *pZNameList )[ zNameIndex ]; // } // End of IF then // else // { // DName zName; // if ( *gName == '?' ) // { // zName = getTemplateName (); // if ( *gName++ != '@' ) // zName = *--gName ? DN_invalid : DN_truncated; // } // else // // Extract the 'zname' to the terminator // zName = DName( gName, '@' ); // This constructor updates 'name' // // Add it to the current list of 'zname's // if ( !pZNameList->isFull ()) // *pZNameList += zName; // // And return the symbol name // return zName; // } // End of IF else // } // End of "UnDecorator" FUNCTION "getZName" // inline DName __near UnDecorator::getOperatorName ( void ) // { // DName operatorName; // DName tmpName; // int udcSeen = FALSE; // // So what type of operator is it ? // switch ( *gName++ ) // { // case 0: // gName--; // End of string, better back-track // return DN_truncated; // case OC_ctor: // case OC_dtor: // // // // The constructor and destructor are special: // // Their operator name is the name of their first enclosing scope, which // // will always be a tag, which may be a template specialization! // // // { // // Use a temporary. Don't want to advance the name pointer // pcchar_t pName = gName; // operatorName = getZName (); // gName = pName; // Undo our lookahead // if ( !operatorName.isEmpty () && ( gName[ -1 ] == OC_dtor )) // operatorName = '~' + operatorName; // return operatorName; // } // End of CASE 'OC_ctor,OC_dtor' // break; // case OC_new: // case OC_delete: // case OC_assign: // case OC_rshift: // case OC_lshift: // case OC_not: // case OC_equal: // case OC_unequal: // operatorName = nameTable[ gName[ -1 ] - OC_new ]; // break; // case OC_udc: // udcSeen = TRUE; // // No break // case OC_index: // case OC_pointer: // case OC_star: // case OC_incr: // case OC_decr: // case OC_minus: // case OC_plus: // case OC_amper: // case OC_ptrmem: // case OC_divide: // case OC_modulo: // case OC_less: // case OC_leq: // case OC_greater: // case OC_geq: // case OC_comma: // case OC_call: // case OC_compl: // case OC_xor: // case OC_or: // case OC_land: // case OC_lor: // case OC_asmul: // case OC_asadd: // case OC_assub: // Regular operators from the first group // operatorName = nameTable[ gName[ -1 ] - OC_index + ( OC_unequal - OC_new + 1 )]; // break; // case '_': // switch ( *gName++ ) // { // case 0: // gName--; // End of string, better back-track // return DN_truncated; // case OC_asdiv: // case OC_asmod: // case OC_asrshift: // case OC_aslshift: // case OC_asand: // case OC_asor: // case OC_asxor: // Regular operators from the extended group // operatorName = nameTable[ gName[ -1 ] - OC_asdiv + ( OC_assub - OC_index + 1 ) + ( OC_unequal - OC_new + 1 )]; // break; // #if ( !NO_COMPILER_NAMES ) // case OC_vftable: // case OC_vbtable: // case OC_vcall: // return nameTable[ gName[ -1 ] - OC_asdiv + ( OC_assub - OC_index + 1 ) + ( OC_unequal - OC_new + 1 )]; // case OC_string: // { // DName result = getStringEncoding( "`string'", TRUE ); // result.setIsNoTE(); // return result; // } // case OC_metatype: // case OC_guard: // case OC_vbdtor: // case OC_vdeldtor: // case OC_defctor: // case OC_sdeldtor: // case OC_vctor: // case OC_vdtor: // case OC_vallctor: // case OC_ehvctor: // case OC_ehvdtor: // case OC_ehvctorvb: // case OC_copyctorclosure: // case OC_locvfctorclosure: // case OC_locvftable: // Special purpose names // case OC_placementDeleteClosure: // case OC_placementArrayDeleteClosure: // return nameTable[ gName[ -1 ] - OC_metatype + ( OC_vcall - OC_asdiv + 1 ) + ( OC_assub - OC_index + 1 ) + ( OC_unequal - OC_new + 1 )]; // case OC_udtthunk: // operatorName = nameTable[ gName[ -1 ] - OC_metatype + ( OC_vcall - OC_asdiv + 1 ) + ( OC_assub - OC_index + 1 ) + ( OC_unequal - OC_new + 1 )]; // tmpName = getOperatorName(); // if ( !tmpName.isEmpty() && tmpName.isUDTThunk() ) // return DN_invalid; // return operatorName + tmpName; // break; // case OC_eh_init: // break; // case OC_rtti_init: // operatorName = nameTable[ gName[ -1 ] - OC_metatype + ( OC_vcall - OC_asdiv + 1 ) + ( OC_assub - OC_index + 1 ) + ( OC_unequal - OC_new + 1 )]; // tmpName = rttiTable[ gName[0] - OC_rtti_TD ]; // switch ( *gName++ ) // { // case OC_rtti_TD: // { // DName result = getDataType ( NULL ); // return result + ' ' + operatorName + tmpName; // } // break; // case OC_rtti_BCD: // { // DName result = operatorName + tmpName; // result += getSignedDimension() + ','; // result += getSignedDimension() + ','; // result += getSignedDimension() + ','; // result += getDimension() + ')'; // return result + '''; // } // break; // case OC_rtti_BCA: // case OC_rtti_CHD: // case OC_rtti_COL: // return operatorName + tmpName; // break; // default: // gName--; // return DN_truncated; // break; // } // break; // #endif // !NO_COMPILER_NAMES // case OC_arrayNew: // case OC_arrayDelete: // operatorName = nameTable[ gName[ -1 ] - OC_metatype + ( OC_vcall - OC_asdiv + 1 ) + ( OC_assub - OC_index + 1 ) + ( OC_unequal - OC_new + 1 ) // #if NO_COMPILER_NAMES // - ( OC_locvfctorclosure - OC_vftable + 1 ) // discount names not in table // #endif // ]; // break; // // Yet another level of nested encodings.... // case '?': // switch( *gName++ ) { // case 0: // gName--; // End of string, better back-track // return DN_truncated; // case OC_anonymousNamespace: // // // // Anonymous namespace (new-style) is a string encoding of the // // machine name and the translation unit name. Since the remainder // // of the name doesn't really fit the dname grammar, skip it. // // There are two '@' markers in the name.... // // // { // DName result = getStringEncoding( "`anonymous namespace'", FALSE ); // result.setIsNoTE(); // return result; // } // default: // return DN_invalid; // } // break; // default: // return DN_invalid; // } // End of SWITCH // break; // default: // return DN_invalid; // } // End of SWITCH // // This really is an operator name, so prefix it with 'operator' // if ( udcSeen ) // operatorName.setIsUDC (); // elif ( !operatorName.isEmpty ()) // operatorName = "operator" + operatorName; // return operatorName; // } // End of "UnDecorator" FUNCTION "getOperatorName" // DName UnDecorator::getStringEncoding ( char *prefix, int wantBody ) // { // DName result = prefix; // // First @ comes right after operator code // if ( *gName++ != '@' || *gName++ != '_' ) { // return DN_invalid; // } // // Skip the string kind // *gName++; // // Get (& discard) the length // getDimension(); // // Get (& discart) the checksum // getDimension(); // while ( *gName && *gName != '@' ) { // // For now, we'll just skip it // gName++; // } // if ( !*gName ) { // gName--; // return DN_truncated; // } // // Eat the terminating '@' // gName++; // return result; // } // DName __near UnDecorator::getScope ( void ) // { // DName scope; // bool fNeedBracket = false; // // Get the list of scopes // while (( scope.status () == DN_valid ) && *gName && ( *gName != '@' )) // { // Insert the scope operator if not the first scope // if ( !scope.isEmpty() ) { // scope = "::" + scope; // if (fNeedBracket) { // scope = '[' + scope; // fNeedBracket = false; // } // } // // Determine what kind of scope it is // if ( *gName == '?' ) // switch ( *++gName ) // { // case '?': // if ( gName[1] == '_' && gName[2] == '?' ) { // // // // Anonymous namespace name (new style) // // // gName++; // scope = getOperatorName () + scope; // // There should be a zname termination @... // if ( *gName == '@' ) { // gName++; // } // } // else if ( !doNameOnly() ) // scope = '`' + getDecoratedName () + ''' + scope; // else // getDecoratedName(); // Skip lexical scope info // break; // case '$': // // It's a template name, which is a kind of zname; back up // // and handle like a zname. // gName--; // scope = getZName () + scope; // break; // case '%': // // // // It an anonymous namespace (old-style); // // skip the (unreadable) name and instead insert // // an appropriate string // // // while ( *gName != '@' ) { // gName++; // } // gName++; // scope = "`anonymous namespace'" + scope; // break; // case 'I': // // // // This is the interface whose method the class is // // implementing // // // gName++; // scope = getZName () + ']' + scope; // fNeedBracket = true; // break; // default: // if ( !doNameOnly() ) // scope = getLexicalFrame () + scope; // else // getLexicalFrame(); // Skip lexical scope info // break; // } // End of SWITCH // else // scope = getZName () + scope; // } // End of WHILE // // Catch error conditions // switch ( *gName ) // { // case 0: // if ( scope.isEmpty() ) // scope = DN_truncated; // else // scope = DName ( DN_truncated ) + "::" + scope; // break; // case '@': // '@' expected to end the scope list // break; // default: // scope = DN_invalid; // break; // } // End of SWITCH // // Return the composed scope // return scope; // } // End of "UnDecorator" FUNCTION "getScope" // DName __near UnDecorator::getSignedDimension ( void ) // { // if ( !*gName ) // return DN_truncated; // elif ( *gName == '?' ) { // gName++; // skip the '?' // return '-' + getDimension(); // } // else // return getDimension(); // } // End of "Undecorator" FUNCTION "getSignedDimension" // DName __near UnDecorator::getDimension ( void ) // { // if ( !*gName ) // return DN_truncated; // elif (( *gName >= '0' ) && ( *gName <= '9' )) // return DName ((unsigned long)( *gName++ - '0' + 1 )); // else // { // unsigned long dim = 0L; // // Don't bother detecting overflow, it's not worth it // while ( *gName != '@' ) // { // if ( !*gName ) // return DN_truncated; // elif (( *gName >= 'A' ) && ( *gName <= 'P' )) // dim = ( dim << 4 ) + ( *gName - 'A' ); // else // return DN_invalid; // gName++; // } // End of WHILE // // Ensure integrity, and return // if ( *gName++ != '@' ) // return DN_invalid; // Should never get here // return dim; // } // End of ELIF else // } // End of "UnDecorator" FUNCTION "getDimension" // int __near UnDecorator::getNumberOfDimensions ( void ) // { // if ( !*gName ) // return 0; // elif (( *gName >= '0' ) && ( *gName <= '9' )) // return (( *gName++ - '0' ) + 1 ); // else // { // int dim = 0; // // Don't bother detecting overflow, it's not worth it // while ( *gName != '@' ) // { // if ( !*gName ) // return 0; // elif (( *gName >= 'A' ) && ( *gName <= 'P' )) // dim = ( dim << 4 ) + ( *gName - 'A' ); // else // return -1; // gName++; // } // End of WHILE // // Ensure integrity, and return // if ( *gName++ != '@' ) // return -1; // Should never get here // return dim; // } // End of ELIF else // } // End of "UnDecorator" FUNCTION "getNumberOfDimensions" // DName __near UnDecorator::getTemplateName ( void ) // { // // // // First make sure we're really looking at a template name // // // if ( gName[0] != '?' || gName[1] != '$' ) // return DN_invalid; // gName += 2; // Skip the marker characters // // // // Stack the replicators, since template names are their own replicator scope: // // // Replicator * pSaveArgList = pArgList; // Replicator * pSaveZNameList = pZNameList; // Replicator * pSaveTemplateArgList = pTemplateArgList; // Replicator localArgList, localZNameList, localTemplateArgList; // pArgList = &localArgList; // pZNameList = &localZNameList; // pTemplateArgList = &localTemplateArgList; // // // // Crack the template name: // // // DName templateName = getZName (); // if ( !templateName.isEmpty ()) // { // templateName += '<' + getTemplateArgumentList (); // if ( templateName.getLastChar () == '>' ) // templateName += ' '; // templateName += '>'; // } // // // // Restore the previous replicators: // // // pArgList = pSaveArgList; // pZNameList = pSaveZNameList; // pTemplateArgList = pSaveTemplateArgList; // // Return the completed 'template-name' // return templateName; // } // End of "UnDecorator" FUNCTION "getTemplateName" // DName __near UnDecorator::getTemplateArgumentList ( void ) // { // int first = TRUE; // DName aList; // while (( aList.status () == DN_valid ) && *gName && ( *gName != AT_endoflist )) // { // // Insert the argument list separator if not the first argument // if ( first ) // first = FALSE; // else // aList += ','; // // Get the individual argument type // int argIndex = *gName - '0'; // // Handle 'template-argument-replicators', otherwise a new argument type // if (( argIndex >= 0 ) && ( argIndex <= 9 )) // { // gName++; // Skip past the replicator // // Append to the argument list // aList += ( *pTemplateArgList )[ argIndex ]; // } // End of IF then // else // { // pcchar_t oldGName = gName; // DName arg; // // // // Extract the 'argument' type // // // if ( *gName == DT_void ) { // gName++; // arg = "void"; // } // elif ( (*gName == '$') && (gName[1] != '$')) { // gName++; // arg = getTemplateConstant(); // } // elif ( *gName == '?' ) { // // // // This is a template-parameter, i.e. we have a "specialization" of // // X. so get the template-parameter-index and use a "generic" name // // for this parameter // // // DName dimension = getSignedDimension(); // if ( haveTemplateParameters()) { // char buffer[16]; // dimension.getString( buffer, 16 ); // char *str = (*m_pGetParameter)(atol(buffer)); // if ( str != NULL ) { // arg = str; // } // else { // arg = "`template-parameter" + dimension + "'"; // } // } // else { // arg = "`template-parameter" + dimension + "'"; // } // } // else { // arg = getPrimaryDataType ( DName() ); // } // // Add it to the current list of 'template-argument's, if it is bigger than a one byte encoding // if ((( gName - oldGName ) > 1 ) && !pTemplateArgList->isFull ()) // *pTemplateArgList += arg; // // Append to the argument list // aList += arg; // } // End of IF else // } // End of WHILE // // Return the completed template argument list // return aList; // } // End of "UnDecorator" FUNCTION "getTemplateArgumentList" // DName __near UnDecorator::getTemplateConstant(void) // { // // // // template-constant ::= // // '0' // // '1' // // '2' // // // switch ( *gName++ ) // { // // // // template-integral-constant ::= // // // // // case TC_integral: // return getSignedDimension (); // // // // template-address-constant ::= // // '@' // Null pointer // // // // // case TC_address: // if ( *gName == TC_nullptr ) // { // gName++; // return "NULL"; // } // else // return DName("&") + getDecoratedName (); // case TC_name: // return getDecoratedName (); // // // // template-floating-point-constant ::= // // // // // case TC_fp: // { // DName mantissa ( getSignedDimension () ); // DName exponent ( getSignedDimension () ); // if ( mantissa.isValid() && exponent.isValid() ) // { // // // // Get string representation of mantissa // // // char buf[100]; // Way overkill for a compiler generated fp constant // if ( !mantissa.getString( &(buf[1]), 100 ) ) // return DN_invalid; // // // // Insert decimal point // // // buf[0] = buf[1]; // if ( buf[0] == '-' ) // { // buf[1] = buf[2]; // buf[2] = '.'; // } // else // buf[1] = '.'; // // // // String it all together // // // return DName( buf ) + 'e' + exponent; // } // End of IF then // else // return DN_truncated; // } // End of BLOCK case TC_fp // case TC_dummy: // { // // // // This is a template-parameter, i.e. we have a "specialization" of // // X. so get the template-parameter-index and use a "generic" name // // for this parameter // // // DName dimension = getSignedDimension(); // if ( haveTemplateParameters()) { // char buffer[16]; // dimension.getString( buffer, 16 ); // char *str = (*m_pGetParameter)(atol(buffer)); // if ( str != NULL ) { // return str; // } // } // return "`template-parameter" + dimension + "'"; // } // break; // case '': // --gName; // return DN_truncated; // default: // return DN_invalid; // } // End of SWITCH // } // End of "UnDecorator" FUNCTION "getTemplateConstant" // inline DName __near UnDecorator::composeDeclaration ( const DName & symbol ) // { // DName declaration; // unsigned int typeCode = getTypeEncoding (); // int symIsUDC = symbol.isUDC (); // // Handle bad typeCode's, or truncation // if ( TE_isbadtype ( typeCode )) // return DN_invalid; // elif ( TE_istruncated ( typeCode )) // return ( DN_truncated + symbol ); // // This is a very complex part. The type of the declaration must be // // determined, and the exact composition must be dictated by this type. // // Is it any type of a function ? // // However, for ease of decoding, treat the 'localdtor' thunk as data, since // // its decoration is a function of the variable to which it belongs and not // // a usual function type of decoration. // #if ( NO_COMPILER_NAMES ) // if ( TE_isthunk ( typeCode )) // return DN_invalid; // if ( TE_isfunction ( typeCode )) // #else // } elif !NO_COMPILER_NAMES { // if ( TE_isfunction ( typeCode ) && !(( TE_isthunk ( typeCode ) && TE_islocaldtor ( typeCode )) || // ( TE_isthunk ( typeCode ) && ( TE_istemplatector ( typeCode ) || TE_istemplatedtor ( typeCode ))))) // #endif // !NO_COMPILER_NAMES // { // // If it is based, then compose the 'based' prefix for the name // if ( TE_isbased ( typeCode )) // if ( doMSKeywords () && doAllocationModel ()) // declaration = ' ' + getBasedType (); // else // declaration |= getBasedType (); // Just lose the 'based-type' // #if ( !NO_COMPILER_NAMES ) // // Check for some of the specially composed 'thunk's // if ( TE_isthunk ( typeCode ) && TE_isvcall ( typeCode )) // { // declaration += symbol + '{' + getCallIndex () + ','; // declaration += getVCallThunkType () + "}' "; // if ( doMSKeywords () && doAllocationLanguage ()) // declaration = ' ' + getCallingConvention () + ' ' + declaration; // What calling convention ? // else // declaration |= getCallingConvention (); // Just lose the 'calling-convention' // } // End of IF then // else // #endif // !NO_COMPILER_NAMES // { // DName vtorDisp; // DName adjustment; // DName thisType; // #if ( !NO_COMPILER_NAMES ) // if ( TE_isthunk ( typeCode )) // { // if ( TE_isvtoradj ( typeCode )) // vtorDisp = getDisplacement (); // adjustment = getDisplacement (); // } // End of IF else // #endif // !NO_COMPILER_NAMES // // Get the 'this-type' for non-static function members // if ( TE_ismember ( typeCode ) && !TE_isstatic ( typeCode )) // if ( doThisTypes ()) // thisType = getThisType (); // else // thisType |= getThisType (); // if ( doMSKeywords ()) // { // // Attach the calling convention // if ( doAllocationLanguage ()) // declaration = getCallingConvention () + declaration; // What calling convention ? // else // declaration |= getCallingConvention (); // Just lose the 'calling-convention' // // Any model specifiers ? // #if !VERS_32BIT // if ( doAllocationModel ()) // if ( TE_isnear ( typeCode )) // declaration = UScore ( TOK_nearSp ) + declaration; // elif ( TE_isfar ( typeCode )) // declaration = UScore ( TOK_farSp ) + declaration; // #endif // } // End of IF // else // declaration |= getCallingConvention (); // Just lose the 'calling-convention' // // Now put them all together // if ( !symbol.isEmpty ()) // if ( !declaration.isEmpty () && !doNameOnly() ) // And the symbol name // declaration += ' ' + symbol; // else // declaration = symbol; // // Compose the return type, catching the UDC case // DName * pDeclarator = 0; // DName returnType; // if ( symIsUDC ) // Is the symbol a UDC operator ? // { // declaration += " " + getReturnType (); // if ( doNameOnly() ) // return declaration; // } // else // { // pDeclarator = gnew DName; // returnType = getReturnType ( pDeclarator ); // } // End of IF else // #if ( !NO_COMPILER_NAMES ) // // Add the displacements for virtual function thunks // if ( TE_isthunk ( typeCode )) // { // if ( TE_isvtoradj ( typeCode )) // declaration += "`vtordisp{" + vtorDisp + ','; // else // declaration += "`adjustor{"; // declaration += adjustment + "}' "; // } // End of IF // #endif // !NO_COMPILER_NAMES // // Add the function argument prototype // declaration += '(' + getArgumentTypes () + ')'; // // If this is a non-static member function, append the 'this' modifiers // if ( TE_ismember ( typeCode ) && !TE_isstatic ( typeCode )) // declaration += thisType; // // Add the 'throw' signature // if ( doThrowTypes ()) // declaration += getThrowTypes (); // else // declaration |= getThrowTypes (); // Just lose the 'throw-types' // // If it has a declarator, then insert it into the declaration, // // sensitive to the return type composition // if ( doFunctionReturns () && pDeclarator ) // { // *pDeclarator = declaration; // declaration = returnType; // } // End of IF // } // End of IF else // } // End of IF then // else // { // declaration += symbol; // // Catch the special handling cases // #if ( !NO_COMPILER_NAMES ) // if ( TE_isvftable ( typeCode )) // return getVfTableType ( declaration ); // elif ( TE_isvbtable ( typeCode )) // return getVbTableType ( declaration ); // elif ( TE_isguard ( typeCode )) // return ( declaration + '{' + getGuardNumber () + "}'" ); // elif ( TE_isthunk ( typeCode ) && TE_islocaldtor ( typeCode )) // declaration += "`local static destructor helper'"; // elif ( TE_isthunk ( typeCode ) && TE_istemplatector ( typeCode )) // declaration += "`template static data member constructor helper'"; // elif ( TE_isthunk ( typeCode ) && TE_istemplatedtor ( typeCode )) // declaration += "`template static data member destructor helper'"; // elif ( TE_ismetaclass ( typeCode )) // // // // Meta-class information has its information in its operator id // // // return declaration; // #else // } elif NO_COMPILER_NAMES { // if ( TE_isvftable ( typeCode ) // || TE_isvbtable ( typeCode ) // || TE_isguard ( typeCode ) // || TE_ismetaclass ( typeCode )) // return DN_invalid; // #endif // NO_COMPILER_NAMES // if ( TE_isthunk( typeCode ) && ( TE_istemplatector( typeCode ) || TE_istemplatedtor( typeCode ))) { // // // // Insert a space before the declaration // // // declaration = " " + declaration; // } // else { // // All others are decorated as data symbols // declaration = getExternalDataType ( declaration ); // } // } // End of IF else // // Prepend the 'virtual' and 'static' attributes for members // if ( TE_ismember ( typeCode )) // { // if ( doMemberTypes ()) // { // if ( TE_isstatic ( typeCode )) // declaration = "static " + declaration; // if ( TE_isvirtual ( typeCode ) || ( TE_isthunk ( typeCode ) && ( TE_isvtoradj ( typeCode ) || TE_isadjustor ( typeCode )))) // declaration = "virtual " + declaration; // } // End of IF // // Prepend the access specifiers // if ( doAccessSpecifiers ()) // if ( TE_isprivate ( typeCode )) // declaration = "private: " + declaration; // elif ( TE_isprotected ( typeCode )) // declaration = "protected: " + declaration; // elif ( TE_ispublic ( typeCode )) // declaration = "public: " + declaration; // } // End of IF // #if ( !NO_COMPILER_NAMES ) // // If it is a thunk, mark it appropriately // if ( TE_isthunk ( typeCode )) // declaration = "[thunk]:" + declaration; // #endif // !NO_COMPILER_NAMES // // Return the composed declaration // return declaration; // } // End of "UnDecorator" FUNCTION "composeDeclaration" // inline int __near UnDecorator::getTypeEncoding ( void ) // { // unsigned int typeCode = 0u; // // Strip any leading '_' which indicates that it is based // if ( *gName == '_' ) // { // TE_setisbased ( typeCode ); // gName++; // } // End of IF // // Now handle the code proper :- // if (( *gName >= 'A' ) && ( *gName <= 'Z' )) // Is it some sort of function ? // { // int code = *gName++ - 'A'; // // Now determine the function type // TE_setisfunction ( typeCode ); // All of them are functions ? // // Determine the calling model // if ( code & TE_far ) // TE_setisfar ( typeCode ); // else // TE_setisnear ( typeCode ); // // Is it a member function or not ? // if ( code < TE_external ) // { // // Record the fact that it is a member // TE_setismember ( typeCode ); // // What access permissions does it have // switch ( code & TE_access ) // { // case TE_private: // TE_setisprivate ( typeCode ); // break; // case TE_protect: // TE_setisprotected ( typeCode ); // break; // case TE_public: // TE_setispublic ( typeCode ); // break; // default: // TE_setisbadtype ( typeCode ); // return typeCode; // } // End of SWITCH // // What type of a member function is it ? // switch ( code & TE_adjustor ) // { // case TE_adjustor: // TE_setisadjustor ( typeCode ); // break; // case TE_virtual: // TE_setisvirtual ( typeCode ); // break; // case TE_static: // TE_setisstatic ( typeCode ); // break; // case TE_member: // break; // default: // TE_setisbadtype ( typeCode ); // return typeCode; // } // End of SWITCH // } // End of IF // } // End of IF then // elif ( *gName == '$' ) // Extended set ? Special handling // { // // What type of symbol is it ? // switch ( *( ++gName )) // { // case SHF_localdtor: // A destructor helper for a local static ? // TE_setislocaldtor ( typeCode ); // break; // case SHF_vcall: // A VCall-thunk ? // TE_setisvcall ( typeCode ); // break; // case SHF_templateStaticDataMemberCtor: // A constructor helper for template static data members // TE_setistemplatector ( typeCode ); // break; // case SHF_templateStaticDataMemberDtor: // A destructor helper for template static data members // TE_setistemplatedtor ( typeCode ); // break; // case 0: // TE_setistruncated ( typeCode ); // break; // case '0': // case '1': // case '2': // case '3': // case '4': // case '5': // Construction displacement adjustor thunks // { // int code = *gName - '0'; // // Set up the principal type information // TE_setisfunction ( typeCode ); // TE_setismember ( typeCode ); // TE_setisvtoradj ( typeCode ); // // Is it 'near' or 'far' ? // if ( code & TE_far ) // TE_setisfar ( typeCode ); // else // TE_setisnear ( typeCode ); // // What type of access protection ? // switch ( code & TE_access_vadj ) // { // case TE_private_vadj: // TE_setisprivate ( typeCode ); // break; // case TE_protect_vadj: // TE_setisprotected ( typeCode ); // break; // case TE_public_vadj: // TE_setispublic ( typeCode ); // break; // default: // TE_setisbadtype ( typeCode ); // return typeCode; // } // End of SWITCH // } // End of CASE '0,1,2,3,4,5' // break; // default: // TE_setisbadtype ( typeCode ); // return typeCode; // } // End of SWITCH // // Advance past the code character // gName++; // } // End of ELIF then // elif (( *gName >= TE_static_d ) && ( *gName <= TE_metatype )) // Non function decorations ? // { // int code = *gName++; // TE_setisdata ( typeCode ); // // What type of symbol is it ? // switch ( code ) // { // case ( TE_static_d | TE_private_d ): // TE_setisstatic ( typeCode ); // TE_setisprivate ( typeCode ); // break; // case ( TE_static_d | TE_protect_d ): // TE_setisstatic ( typeCode ); // TE_setisprotected ( typeCode ); // break; // case ( TE_static_d | TE_public_d ): // TE_setisstatic ( typeCode ); // TE_setispublic ( typeCode ); // break; // case TE_global: // TE_setisglobal ( typeCode ); // break; // case TE_guard: // TE_setisguard ( typeCode ); // break; // case TE_local: // TE_setislocal ( typeCode ); // break; // case TE_vftable: // TE_setisvftable ( typeCode ); // break; // case TE_vbtable: // TE_setisvbtable ( typeCode ); // break; // case TE_metatype: // TE_setismetaclass ( typeCode ); // break; // default: // TE_setisbadtype ( typeCode ); // return typeCode; // } // End of SWITCH // } // End of ELIF then // elif ( *gName ) // TE_setisbadtype ( typeCode ); // else // TE_setistruncated ( typeCode ); // // Return the composed type code // return typeCode; // } // End of "UnDecorator" FUNCTION "getTypeEncoding" // DName __near UnDecorator::getBasedType ( void ) // { // DName basedDecl ( UScore ( TOK_basedLp )); // // What type of 'based' is it ? // if ( *gName ) // { // switch ( *gName++ ) // { // #if !VERS_32BIT // case BT_segname: // basedDecl += UScore ( TOK_segnameLpQ ) + getSegmentName () + "")"; // break; // case BT_segment: // basedDecl += DName ( "NYI:" ) + UScore ( TOK_segment ); // break; // #endif // case BT_void: // basedDecl += "void"; // break; // #if !VERS_32BIT // case BT_self: // basedDecl += UScore ( TOK_self ); // break; // case BT_nearptr: // basedDecl += DName ( "NYI:" ) + UScore ( TOK_nearP ); // break; // case BT_farptr: // basedDecl += DName ( "NYI:" ) + UScore ( TOK_farP ); // break; // case BT_hugeptr: // basedDecl += DName ( "NYI:" ) + UScore ( TOK_hugeP ); // break; // case BT_segaddr: // basedDecl += "NYI:"; // break; // #else // case BT_nearptr: // basedDecl += getScopedName(); // break; // #endif // case BT_basedptr: // // // // Note: based pointer on based pointer is reserved // // // return DN_invalid; // } // End of SWITCH // } // End of IF else // else // basedDecl += DN_truncated; // // Close the based syntax // basedDecl += ") "; // // Return completed based declaration // return basedDecl; // } // End of "UnDecorator" FUNCTION "getBasedType" // DName __near UnDecorator::getScopedName ( void ) // { // DName name; // // Get the beginning of the name // name = getZName (); // // Now the scope (if any) // if (( name.status () == DN_valid ) && *gName && ( *gName != '@' )) // name = getScope () + "::" + name; // // Skip the trailing '@' // if ( *gName == '@' ) // gName++; // elif ( *gName ) // name = DN_invalid; // elif ( name.isEmpty ()) // name = DN_truncated; // else // name = DName ( DN_truncated ) + "::" + name; // // And return the complete name // return name; // } // End of "UnDecorator" FUNCTION "getECSUName" // inline DName UnDecorator::getECSUName ( void ) { return getScopedName(); } // inline DName __near UnDecorator::getEnumType ( void ) // { // DName ecsuName; // if ( *gName ) // { // // What type of an 'enum' is it ? // switch ( *gName ) // { // case ET_schar: // case ET_uchar: // ecsuName = "char "; // break; // case ET_sshort: // case ET_ushort: // ecsuName = "short "; // break; // case ET_sint: // break; // case ET_uint: // ecsuName = "int "; // break; // case ET_slong: // case ET_ulong: // ecsuName = "long "; // break; // default: // return DN_invalid; // } // End of SWITCH // // Add the 'unsigned'ness if appropriate // switch ( *gName++ ) // { // case ET_uchar: // case ET_ushort: // case ET_uint: // case ET_ulong: // ecsuName = "unsigned " + ecsuName; // break; // } // End of SWITCH // // Now return the composed name // return ecsuName; // } // End of IF then // else // return DN_truncated; // } // End of "UnDecorator" FUNCTION "getEnumType" // DName __near UnDecorator::getCallingConvention ( void ) // { // if ( *gName ) // { // unsigned int callCode = ((unsigned int)*gName++ ) - 'A'; // // What is the primary calling convention // #if CC_COR // if (( callCode >= CC_cdecl ) && ( callCode <= CC_cocall )) // #else // CC_COR // if (( callCode >= CC_cdecl ) && ( callCode <= CC_interrupt )) // #endif // CC_COR // { // DName callType; // // Now, what type of 'calling-convention' is it, 'interrupt' is special ? // if ( doMSKeywords ()) // #if !VERS_32BIT // if ( callCode == CC_interrupt ) // callType = UScore ( TOK_interrupt ); // else // #endif // { // switch ( callCode & ~CC_saveregs ) // { // case CC_cdecl: // callType = UScore ( TOK_cdecl ); // break; // case CC_pascal: // callType = UScore ( TOK_pascal ); // break; // case CC_thiscall: // callType = UScore ( TOK_thiscall ); // break; // case CC_stdcall: // callType = UScore ( TOK_stdcall ); // break; // case CC_fastcall: // callType = UScore ( TOK_fastcall ); // break; // case CC_cocall: // callType = UScore ( TOK_cocall ); // break; // } // End of SWITCH // // Has it also got 'saveregs' marked ? // #if !VERS_32BIT // if ( callCode & CC_saveregs ) // callType += ' ' + UScore ( TOK_saveregs ); // #endif // } // End of IF else // // And return // return callType; // } // End of IF then // else // return DN_invalid; // } // End of IF then // else // return DN_truncated; // } // End of "UnDecorator" FUNCTION "getCallingConvention" // DName __near UnDecorator::getReturnType ( DName * pDeclarator ) // { // if ( *gName == '@' ) // Return type for constructors and destructors ? // { // gName++; // return DName ( pDeclarator ); // } // End of IF then // else // return getDataType ( pDeclarator ); // } // End of "UnDecorator" FUNCTION "getReturnType" // DName __near UnDecorator::getDataType ( DName * pDeclarator ) // { // DName superType ( pDeclarator ); // // What type is it ? // switch ( *gName ) // { // case 0: // return ( DN_truncated + superType ); // case DT_void: // gName++; // if ( superType.isEmpty ()) // return "void"; // else // return "void " + superType; // case '?': // { // gName++; // Skip the '?' // superType = getDataIndirectType ( superType, 0, DName (), 0); // return getPrimaryDataType ( superType ); // return superType; // } // End of CASE '?' // default: // return getPrimaryDataType ( superType ); // } // End of SWITCH // } // End of "UnDecorator" FUNCTION "getDataType" // DName __near UnDecorator::getPrimaryDataType ( const DName & superType ) // { // DName cvType; // switch ( *gName ) // { // case 0: // return ( DN_truncated + superType ); // case PDT_volatileReference: // cvType = "volatile"; // if ( !superType.isEmpty ()) // cvType += ' '; // // No break // case PDT_reference: // { // DName copyOfSuperType ( superType ); // gName++; // return getReferenceType ( cvType, copyOfSuperType.setPtrRef ()); // } // End of CASE 'PDT_reference' // case PDT_extend: // { // // // // Extended Primary Data Type (items overlooked in original design): // // prefixed by '$$'. // // // if ( gName[1] != PDT_extend ) // if ( gName[1] == '' ) // return DN_truncated + superType; // else // return DN_invalid; // gName += 2; // switch ( *gName ) // { // case PDT_ex_function: // gName++; // return getFunctionIndirectType( superType ); // case PDT_ex_other: // gName++; // return getPtrRefDataType( superType, /* isPtr = */ TRUE ); // case PDT_ex_qualified: // gName++; // return(getBasicDataType(getDataIndirectType ( superType, 0, DName (), 0))); // case 0: // return ( DN_truncated + superType ); // default: // return DN_invalid; // } // } // default: // return getBasicDataType ( superType ); // } // End of SWITCH // } // End of "UnDecorator" FUNCTION "getPrimaryDataType" // DName __near UnDecorator::getArgumentTypes ( void ) // { // switch ( *gName ) // { // case AT_ellipsis: // return ( gName++, "..." ); // case AT_void: // return ( gName++, "void" ); // default: // { // DName arguments ( getArgumentList ()); // // Now, is it a varargs function or not ? // if ( arguments.status () == DN_valid ) // switch ( *gName ) // { // case 0: // return arguments; // case AT_ellipsis: // return ( gName++, arguments + ",..." ); // case AT_endoflist: // return ( gName++, arguments ); // default: // return DN_invalid; // } // End of SWITCH // else // return arguments; // } // End of DEFAULT // } // End of SWITCH // } // End of "UnDecorator" FUNCTION "getArgumentTypes" // DName __near UnDecorator::getArgumentList ( void ) // { // int first = TRUE; // DName aList; // while (( aList.status () == DN_valid ) && ( *gName != AT_endoflist ) && ( *gName != AT_ellipsis )) // { // // Insert the argument list separator if not the first argument // if ( first ) // first = FALSE; // else // aList += ','; // // Get the individual argument type // if ( *gName ) // { // int argIndex = *gName - '0'; // // Handle 'argument-replicators', otherwise a new argument type // if (( argIndex >= 0 ) && ( argIndex <= 9 )) // { // gName++; // Skip past the replicator // // Append to the argument list // aList += ( *pArgList )[ argIndex ]; // } // End of IF then // else // { // pcchar_t oldGName = gName; // // Extract the 'argument' type // DName arg ( getPrimaryDataType ( DName ())); // // Add it to the current list of 'argument's, if it is bigger than a one byte encoding // if ((( gName - oldGName ) > 1 ) && !pArgList->isFull ()) // *pArgList += arg; // // Append to the argument list // aList += arg; // } // End of IF else // } // End of IF then // else // { // aList += DN_truncated; // break; // } // End of IF else // } // End of WHILE // // Return the completed argument list // return aList; // } // End of "UnDecorator" FUNCTION "getArgumentList" // DName __near UnDecorator::getThrowTypes ( void ) // { // if ( *gName ) // if ( *gName == AT_ellipsis ) // Handle ellipsis here to suppress the 'throw' signature // return ( gName++, DName ()); // else // return ( " throw(" + getArgumentTypes () + ')' ); // else // return ( DName ( " throw(" ) + DN_truncated + ')' ); // } // End of "UnDecorator" FUNCTION "getThrowTypes" // DName __near UnDecorator::getBasicDataType ( const DName & superType ) // { // if ( *gName ) // { // unsigned char bdtCode = *gName++; // unsigned char extended_bdtCode; // int pCvCode = -1; // DName basicDataType; // // Extract the principal type information itself, and validate the codes // switch ( bdtCode ) // { // case BDT_schar: // case BDT_char: // case ( BDT_char | BDT_unsigned ): // basicDataType = "char"; // break; // case BDT_short: // case ( BDT_short | BDT_unsigned ): // basicDataType = "short"; // break; // case BDT_int: // case ( BDT_int | BDT_unsigned ): // basicDataType = "int"; // break; // case BDT_long: // case ( BDT_long | BDT_unsigned ): // basicDataType = "long"; // break; // #if !VERS_32BIT // case BDT_segment: // basicDataType = UScore ( TOK_segment ); // break; // #endif // case BDT_float: // basicDataType = "float"; // break; // case BDT_longdouble: // basicDataType = "long "; // // No break // case BDT_double: // basicDataType += "double"; // break; // case BDT_pointer: // case ( BDT_pointer | BDT_const ): // case ( BDT_pointer | BDT_volatile ): // case ( BDT_pointer | BDT_const | BDT_volatile ): // pCvCode = ( bdtCode & ( BDT_const | BDT_volatile )); // break; // case BDT_extend: // switch(extended_bdtCode = *gName++) { // case BDT_bool: // basicDataType = "bool"; // break; // case BDT_int8: // case ( BDT_int8 | BDT_unsigned ): // basicDataType = "__int8"; // break; // case BDT_int16: // case ( BDT_int16 | BDT_unsigned ): // basicDataType = "__int16"; // break; // case BDT_int32: // case ( BDT_int32 | BDT_unsigned ): // basicDataType = "__int32"; // break; // case BDT_int64: // case ( BDT_int64 | BDT_unsigned ): // basicDataType = "__int64"; // break; // case BDT_int128: // case ( BDT_int128 | BDT_unsigned ): // basicDataType = "__int128"; // break; // case BDT_wchar_t: // basicDataType = "wchar_t"; // break; // #if CC_COR || CC_COR2 // case BDT_coclass: // case BDT_interface: // { // gName--; // Backup, since 'ecsu-data-type' does it's own decoding // basicDataType = getECSUDataType(); // if ( basicDataType.isEmpty()) { // return basicDataType; // } // } // break; // #endif // CC_COR || CC_COR2 // default: // basicDataType = "UNKNOWN"; // break; // } // break; // default: // gName--; // Backup, since 'ecsu-data-type' does it's own decoding // basicDataType = getECSUDataType (); // if ( basicDataType.isEmpty ()) // return basicDataType; // break; // } // End of SWITCH // // What type of basic data type composition is involved ? // if ( pCvCode == -1 ) // Simple ? // { // // Determine the 'signed/unsigned'ness // switch ( bdtCode ) // { // case ( BDT_char | BDT_unsigned ): // case ( BDT_short | BDT_unsigned ): // case ( BDT_int | BDT_unsigned ): // case ( BDT_long | BDT_unsigned ): // basicDataType = "unsigned " + basicDataType; // break; // case BDT_schar: // basicDataType = "signed " + basicDataType; // break; // case BDT_extend: // switch ( extended_bdtCode ) // { // case ( BDT_int8 | BDT_unsigned ): // case ( BDT_int16 | BDT_unsigned ): // case ( BDT_int32 | BDT_unsigned ): // case ( BDT_int64 | BDT_unsigned ): // case ( BDT_int128 | BDT_unsigned ): // basicDataType = "unsigned " + basicDataType; // break; // } // End of SWITCH // break; // } // End of SWITCH // // Add the indirection type to the type // if ( !superType.isEmpty ()) // basicDataType += ' ' + superType; // // And return the completed type // return basicDataType; // } // End of IF then // else // { // DName cvType; // DName copyOfSuperType ( superType ); // // Is it 'const/volatile' qualified ? // if ( superType . isEmpty() ) // { // // // // const/volatile are redundantly encoded, except at the start // // of a "type only" context. In such a context, the super-type // // is empty. // // // if ( pCvCode & BDT_const ) // { // cvType = "const"; // if ( pCvCode & BDT_volatile ) // cvType += " volatile"; // } // End of IF then // elif ( pCvCode & BDT_volatile ) // cvType = "volatile"; // } // End of IF then // // Construct the appropriate pointer type declaration // return getPointerType ( cvType, copyOfSuperType ); // } // End of IF else // } // End of IF then // else // return ( DN_truncated + superType ); // } // End of "UnDecorator" FUNCTION "getBasicDataType" // DName __near UnDecorator::getECSUDataType ( void ) // { // // Extract the principal type information itself, and validate the codes // int fPrefix = doEcsu() && !doNameOnly(); // DName Prefix; // switch ( *gName++ ) // { // case 0: // gName--; // Backup to permit later error recovery to work safely // return "`unknown ecsu'" + DN_truncated; // case BDT_union: // Prefix = "union "; // break; // case BDT_struct: // Prefix = "struct "; // break; // case BDT_class: // Prefix = "class "; // break; // #if CC_COR || CC_COR2 // case BDT_coclass: // Prefix = "coclass "; // break; // case BDT_interface: // Prefix = "interface "; // break; // #endif // CC_COR || CC_COR2 // case BDT_enum: // fPrefix = doEcsu(); // Prefix = "enum " + getEnumType (); // break; // // default: // // return DN_invalid; // } // End of SWITCH // DName ecsuDataType; // if ( fPrefix ) // ecsuDataType = Prefix; // // Get the 'class/struct/union' name // ecsuDataType += getECSUName (); // // And return the formed 'ecsu-data-type' // return ecsuDataType; // } // End of "UnDecorator" FUNCTION "getECSUDataType" // // // // Undecorator::getFunctionIndirectType // // // // Note: this function gets both the function-indirect-type and the function-type. // // // DName UnDecorator::getFunctionIndirectType( const DName & superType ) // { // if ( ! *gName ) // return DN_truncated + superType; // if ( ! IT_isfunction( *gName )) // return DN_invalid; // int fitCode = *gName++ - '6'; // if ( fitCode == ( '_' - '6' )) // { // if ( *gName ) // { // fitCode = *gName++ - 'A' + FIT_based; // if (( fitCode < FIT_based ) || ( fitCode > ( FIT_based | FIT_far | FIT_member ))) // fitCode = -1; // } // End of IF then // else // return ( DN_truncated + superType ); // } // End of IF then // elif (( fitCode < FIT_near ) || ( fitCode > ( FIT_far | FIT_member ))) // fitCode = -1; // // Return if invalid name // if ( fitCode == -1 ) // return DN_invalid; // // Otherwise, what are the function indirect attributes // DName thisType; // DName fitType = superType; // // Is it a pointer to member function ? // if ( fitCode & FIT_member ) // { // fitType = "::" + fitType; // if ( *gName ) // fitType = ' ' + getScope () + fitType; // else // fitType = DN_truncated + fitType; // if ( *gName ) // if ( *gName == '@' ) // gName++; // else // return DN_invalid; // else // return ( DN_truncated + fitType ); // if ( doThisTypes ()) // thisType = getThisType (); // else // thisType |= getThisType (); // } // End of IF // // Is it a based allocated function ? // if ( fitCode & FIT_based ) // if ( doMSKeywords ()) // fitType = ' ' + getBasedType () + fitType; // else // fitType |= getBasedType (); // Just lose the 'based-type' // // Get the 'calling-convention' // if ( doMSKeywords ()) // { // fitType = getCallingConvention () + fitType; // // Is it a near or far function pointer // #if !VERS_32BIT // fitType = UScore ((( fitCode & FIT_far ) ? TOK_farSp : TOK_nearSp )) + fitType; // #endif // } // End of IF then // else // fitType |= getCallingConvention (); // Just lose the 'calling-convention' // // Parenthesise the indirection component, and work on the rest // if ( ! superType . isEmpty() ) { // fitType = '(' + fitType + ')'; // } // // Get the rest of the 'function-type' pieces // DName * pDeclarator = gnew DName; // DName returnType ( getReturnType ( pDeclarator )); // fitType += '(' + getArgumentTypes () + ')'; // if ( doThisTypes () && ( fitCode & FIT_member )) // fitType += thisType; // if ( doThrowTypes ()) // fitType += getThrowTypes (); // else // fitType |= getThrowTypes (); // Just lose the 'throw-types' // // Now insert the indirected declarator, catch the allocation failure here // if ( pDeclarator ) // *pDeclarator = fitType; // else // return DN_error; // // And return the composed function type (now in 'returnType' ) // return returnType; // } // DName __near UnDecorator::getPtrRefType ( const DName & cvType, const DName & superType, int isPtr ) // { // // Doubles up as 'pointer-type' and 'reference-type' // if ( *gName ) // if ( IT_isfunction ( *gName )) // Is it a function or data indirection ? // { // DName fitType = ( isPtr ? '*' : '&' ); // if ( !cvType.isEmpty () && ( superType.isEmpty () || !superType.isPtrRef ())) // fitType += cvType; // if ( !superType.isEmpty ()) // fitType += superType; // return getFunctionIndirectType( fitType ); // } // End of IF then // else // { // // Otherwise, it is either a pointer or a reference to some data type // DName innerType ( getDataIndirectType ( superType, ( isPtr ? '*' : '&' ), cvType )); // return getPtrRefDataType ( innerType, isPtr ); // } // End of IF else // else // { // DName trunk ( DN_truncated ); // trunk += ( isPtr ? '*' : '&' ); // if ( !cvType.isEmpty ()) // trunk += cvType; // if ( !superType.isEmpty ()) // { // if ( !cvType.isEmpty ()) // trunk += ' '; // trunk += superType; // } // End of IF // return trunk; // } // End of IF else // } // End of "UnDecorator" FUNCTION "getPtrRefType" // DName __near UnDecorator::getDataIndirectType ( const DName & superType, char prType, const DName & cvType, int thisFlag ) // { // if ( *gName ) // { // unsigned int ditCode = ( *gName - (( *gName >= 'A' ) ? (unsigned int)'A': (unsigned int)( '0' - 26 ))); // DName msExtension; // if ( doMSKeywords ()) // { // int fContinue = TRUE; // do // { // switch ( ditCode & DIT_modelmask ) // { // case DIT_ptr64: // if ( !msExtension.isEmpty()) // msExtension = msExtension + ' ' + UScore( TOK_ptr64 ); // else // msExtension = UScore( TOK_ptr64 ); // gName++; // ditCode = ( *gName - (( *gName >= 'A' ) ? (unsigned int)'A': (unsigned int)( '0' - 26 ))); // break; // case DIT_restrict: // if ( !msExtension.isEmpty()) // msExtension = msExtension + ' ' + UScore( TOK_restrict ); // else // msExtension = UScore( TOK_restrict ); // gName++; // ditCode = ( *gName - (( *gName >= 'A' ) ? (unsigned int)'A': (unsigned int)( '0' - 26 ))); // break; // default: // fContinue = FALSE; // break; // } // } while (fContinue); // } // gName++; // Skip to next character in name // // Is it a valid 'data-indirection-type' ? // if (( ditCode >= DIT_near ) && ( ditCode <= ( DIT_const | DIT_volatile | DIT_modelmask | DIT_member ))) // { // DName ditType ( prType ); // if ( !msExtension.isEmpty()) // ditType = ditType + ' ' + msExtension; // // If it is a member, then these attributes immediately precede the indirection token // if ( ditCode & DIT_member ) // { // // If it is really 'this-type', then it cannot be any form of pointer to member // if ( thisFlag ) // return DN_invalid; // // Otherwise, extract the scope for the PM // if ( prType != '' ) // { // ditType = "::" + ditType; // if ( *gName ) // ditType = getScope () + ditType; // else // ditType = DN_truncated + ditType; // } // elif ( *gName ) // { // // // // The scope is ignored for special uses of data-indirect-type, such // // as storage-convention. I think it's a // // with Member storage convention, as that is already covered in the // // scope of the name. However, we don't want to change the dname scheme, // // so we're stuck with it. // // // ditType |= getScope (); // } // // Now skip the scope terminator // if ( !*gName ) // ditType += DN_truncated; // elif ( *gName++ != '@' ) // return DN_invalid; // } // End of IF // // Add the 'model' attributes (prefixed) as appropriate // if ( doMSKeywords ()) { // switch ( ditCode & DIT_modelmask ) // { // #if !VERS_32BIT // case DIT_near: // if ( do32BitNear ()) // ditType = UScore ( TOK_near ) + ditType; // break; // case DIT_far: // ditType = UScore ( TOK_far ) + ditType; // break; // case DIT_huge: // ditType = UScore ( TOK_huge ) + ditType; // break; // #endif // case DIT_based: // // The 'this-type' can never be 'based' // if ( thisFlag ) // return DN_invalid; // ditType = getBasedType () + ditType; // break; // } // End of SWITCH // } // End of IF // elif (( ditCode & DIT_modelmask ) == DIT_based ) // ditType |= getBasedType (); // Just lose the 'based-type' // // Handle the 'const' and 'volatile' attributes // if ( ditCode & DIT_volatile ) // ditType = "volatile " + ditType; // if ( ditCode & DIT_const ) // ditType = "const " + ditType; // // Append the supertype, if not 'this-type' // if ( !thisFlag ) // if ( !superType.isEmpty ()) // { // // Is the super context included 'cv' information, ensure that it is added appropriately // if ( superType.isPtrRef () || cvType.isEmpty ()) // ditType += ' ' + superType; // else // ditType += ' ' + cvType + ' ' + superType; // } // End of IF then // elif ( !cvType.isEmpty ()) // ditType += ' ' + cvType; // // Make sure qualifiers aren't re-applied // ditType.setPtrRef (); // // Finally, return the composed 'data-indirection-type' (with embedded sub-type) // return ditType; // } // End of IF then // else // return DN_invalid; // } // End of IF then // elif ( !thisFlag && !superType.isEmpty ()) // { // // Is the super context included 'cv' information, ensure that it is added appropriately // if ( superType.isPtrRef () || cvType.isEmpty ()) // return ( DN_truncated + superType ); // else // return ( DN_truncated + cvType + ' ' + superType ); // } // End of ELIF then // elif ( !thisFlag && !cvType.isEmpty ()) // return ( DN_truncated + cvType ); // else // return DN_truncated; // } // End of "UnDecorator" FUNCTION "getDataIndirectType" // inline DName __near UnDecorator::getPtrRefDataType ( const DName & superType, int isPtr ) // { // // Doubles up as 'pointer-data-type' and 'reference-data-type' // if ( *gName ) // { // // Is this a 'pointer-data-type' ? // if ( isPtr && ( *gName == PoDT_void )) // { // gName++; // Skip this character // if ( superType.isEmpty ()) // return "void"; // else // return "void " + superType; // } // End of IF // // Otherwise it may be a 'reference-data-type' // if ( *gName == RDT_array ) // An array ? // { // gName++; // return getArrayType( superType ); // } // End of IF // // Otherwise, it is a 'basic-data-type' // return getBasicDataType ( superType ); // } // End of IF then // else // return ( DN_truncated + superType ); // } // End of "UnDecorator" FUNCTION "getPtrRefDataType" // inline DName __near UnDecorator::getArrayType ( const DName & superType ) // { // if ( *gName ) // { // int noDimensions = getNumberOfDimensions (); // if ( noDimensions < 0 ) // noDimensions = 0; // if ( !noDimensions ) // return getBasicDataType ( DName ( '[' ) + DN_truncated + ']' ); // else // { // DName arrayType; // while ( noDimensions-- ) // arrayType += '[' + getDimension () + ']'; // // If it is indirect, then parenthesise the 'super-type' // if ( !superType.isEmpty ()) // arrayType = '(' + superType + ')' + arrayType; // // Return the finished array dimension information // return getPrimaryDataType ( arrayType ); // } // End of IF else // } // End of IF // elif ( !superType.isEmpty ()) // return getBasicDataType ( '(' + superType + ")[" + DN_truncated + ']' ); // else // return getBasicDataType ( DName ( '[' ) + DN_truncated + ']' ); // } // End of "UnDecorator" FUNCTION "getArrayType" // inline DName __near UnDecorator::getLexicalFrame ( void ) { return '`' + getDimension () + '''; } // inline DName __near UnDecorator::getStorageConvention ( void ) { return getDataIndirectType (); } // inline DName __near UnDecorator::getDataIndirectType () { return getDataIndirectType ( DName (), 0, DName ()); } // inline DName __near UnDecorator::getThisType ( void ) { return getDataIndirectType ( DName (), 0, DName (), TRUE ); } // inline DName __near UnDecorator::getPointerType ( const DName & cv, const DName & name ) // { return getPtrRefType ( cv, name, TRUE ); } // inline DName __near UnDecorator::getReferenceType ( const DName & cv, const DName & name ) // { return getPtrRefType ( cv, name, FALSE ); } // inline DName __near UnDecorator::getSegmentName ( void ) { return getZName (); } // #if ( !NO_COMPILER_NAMES ) // inline DName __near UnDecorator::getDisplacement ( void ) { return getDimension (); } // inline DName __near UnDecorator::getCallIndex ( void ) { return getDimension (); } // inline DName __near UnDecorator::getGuardNumber ( void ) { return getDimension (); } // inline DName __near UnDecorator::getVbTableType ( const DName & superType ) // { return getVfTableType ( superType ); } // inline DName __near UnDecorator::getVCallThunkType ( void ) // { // #if VERS_32BIT // switch (*gName) { // case VMT_nTnCnV: // ++gName; // return DName("{flat}"); // case 0: // return DN_truncated; // default: // return DN_invalid; // } // #else // DName vcallType = '{'; // // Get the 'this' model, and validate all values // switch ( *gName ) // { // case VMT_nTnCnV: // case VMT_nTfCnV: // case VMT_nTnCfV: // case VMT_nTfCfV: // case VMT_nTnCbV: // case VMT_nTfCbV: // vcallType += UScore ( TOK_nearSp ); // break; // case VMT_fTnCnV: // case VMT_fTfCnV: // case VMT_fTnCfV: // case VMT_fTfCfV: // case VMT_fTnCbV: // case VMT_fTfCbV: // vcallType += UScore ( TOK_farSp ); // break; // case 0: // return DN_truncated; // default: // return DN_invalid; // } // End of SWITCH // // Always append 'this' // vcallType += "this, "; // // Get the 'call' model // switch ( *gName ) // { // case VMT_nTnCnV: // case VMT_fTnCnV: // case VMT_nTnCfV: // case VMT_fTnCfV: // case VMT_nTnCbV: // case VMT_fTnCbV: // vcallType += UScore ( TOK_nearSp ); // break; // case VMT_nTfCnV: // case VMT_fTfCnV: // case VMT_nTfCfV: // case VMT_fTfCfV: // case VMT_nTfCbV: // case VMT_fTfCbV: // vcallType += UScore ( TOK_farSp ); // break; // } // End of SWITCH // // Always append 'call' // vcallType += "call, "; // // Get the 'vfptr' model // switch ( *gName++ ) // Last time, so advance the pointer // { // case VMT_nTnCnV: // case VMT_nTfCnV: // case VMT_fTnCnV: // case VMT_fTfCnV: // vcallType += UScore ( TOK_nearSp ); // break; // case VMT_nTnCfV: // case VMT_nTfCfV: // case VMT_fTnCfV: // case VMT_fTfCfV: // vcallType += UScore ( TOK_farSp ); // break; // case VMT_nTfCbV: // case VMT_fTnCbV: // case VMT_fTfCbV: // case VMT_nTnCbV: // vcallType += getBasedType (); // break; // } // End of SWITCH // // Always append 'vfptr' // vcallType += "vfptr}"; // // And return the resultant 'vcall-model-type' // return vcallType; // #endif // } // End of "UnDecorator" FUNCTION "getVCallThunk" // // inline DName __near UnDecorator::getVfTableType (const DName & superType ) // { // DName vxTableName = superType; // if ( vxTableName.isValid () && *gName ) // { // vxTableName = getStorageConvention () + ' ' + vxTableName; // if ( vxTableName.isValid ()) // { // if ( *gName != '@' ) // { // vxTableName += "{for "; // while ( vxTableName.isValid () && *gName && ( *gName != '@' )) // { // vxTableName += '`' + getScope () + '''; // // Skip the scope delimiter // if ( *gName == '@' ) // gName++; // // Close the current scope, and add a conjunction for the next (if any) // if ( vxTableName.isValid () && ( *gName != '@' )) // vxTableName += "s "; // } // End of WHILE // if ( vxTableName.isValid ()) // { // if ( !*gName ) // vxTableName += DN_truncated; // vxTableName += '}'; // } // End of IF // } // End of IF // // Skip the 'vpath-name' terminator // if ( *gName == '@' ) // gName++; // } // End of IF // } // End of IF then // elif ( vxTableName.isValid ()) // vxTableName = DN_truncated + vxTableName; // return vxTableName; // } // End of "UnDecorator" FUNCTION "getVfTableType" // #endif // !NO_COMPILER_NAMES // inline DName __near UnDecorator::getExternalDataType ( const DName & superType ) // { // // Create an indirect declarator for the the rest // DName * pDeclarator = gnew DName (); // DName declaration = getDataType ( pDeclarator ); // // Now insert the declarator into the declaration along with its 'storage-convention' // if (pDeclarator) { // *pDeclarator = getStorageConvention () + ' ' + superType; // } // return declaration; // } // End of "UnDecorator" FUNCTION "getExternalDataType" // inline int __near UnDecorator::doUnderScore () { return !( disableFlags & UNDNAME_NO_LEADING_UNDERSCORES ); } // inline int __near UnDecorator::doMSKeywords () { return !( disableFlags & UNDNAME_NO_MS_KEYWORDS ); } // inline int __near UnDecorator::doFunctionReturns () { return !( disableFlags & UNDNAME_NO_FUNCTION_RETURNS ); } // inline int __near UnDecorator::doAllocationModel () { return !( disableFlags & UNDNAME_NO_ALLOCATION_MODEL ); } // inline int __near UnDecorator::doAllocationLanguage () { return !( disableFlags & UNDNAME_NO_ALLOCATION_LANGUAGE ); } // #if 0 // inline int __near UnDecorator::doMSThisType () { return !( disableFlags & UNDNAME_NO_MS_THISTYPE ); } // inline int __near UnDecorator::doCVThisType () { return !( disableFlags & UNDNAME_NO_CV_THISTYPE ); } // #endif // inline int __near UnDecorator::doThisTypes () { return (( disableFlags & UNDNAME_NO_THISTYPE ) != UNDNAME_NO_THISTYPE ); } // inline int __near UnDecorator::doAccessSpecifiers () { return !( disableFlags & UNDNAME_NO_ACCESS_SPECIFIERS ); } // inline int __near UnDecorator::doThrowTypes () { return !( disableFlags & UNDNAME_NO_THROW_SIGNATURES ); } // inline int __near UnDecorator::doMemberTypes () { return !( disableFlags & UNDNAME_NO_MEMBER_TYPE ); } // inline int __near UnDecorator::doReturnUDTModel () { return !( disableFlags & UNDNAME_NO_RETURN_UDT_MODEL ); } // inline int __near UnDecorator::do32BitNear () { return !( disableFlags & UNDNAME_32_BIT_DECODE ); } // inline int __near UnDecorator::doNameOnly () { return ( disableFlags & UNDNAME_NAME_ONLY ); } // inline int __near UnDecorator::doTypeOnly () { return ( disableFlags & UNDNAME_TYPE_ONLY ); } // inline int __near UnDecorator::haveTemplateParameters () { return ( disableFlags & UNDNAME_HAVE_PARAMETERS); } // inline int __near UnDecorator::doEcsu () { return !( disableFlags & UNDNAME_NO_ECSU ); } // inline int __near UnDecorator::doNoIdentCharCheck () { return ( disableFlags & UNDNAME_NO_IDENT_CHAR_CHECK ); } // pcchar_t __near UnDecorator::UScore ( Tokens tok ) // { // #if !VERS_32BIT // if ((( tok == TOK_nearSp ) || ( tok == TOK_nearP )) && !do32BitNear ()) // return tokenTable[ tok ] + 6; // Skip '__near' // #endif // if ( doUnderScore ()) // return tokenTable[ tok ]; // else // return tokenTable[ tok ] + 2 ; // } // End of "UnDecorator" FUNCTION "UScore" // // Include the string composition support classes. Mostly inline stuff, and // // not important to the algorithm. // #include "undname.inl" ================================================ FILE: Sysmon/undname.h ================================================ // // Copyright (c) Microsoft Corporation. All rights reserved. // // // This source code is licensed under Microsoft Shared Source License // Version 1.0 for Windows CE. // For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223. // // #if !defined(_M_I86) // // The 32-bit compiler // #define __far // #define __near // #define __pascal // #define __loadds // #endif // typedef char * pchar_t; // typedef const char * pcchar_t; // typedef void * ( __cdecl * Alloc_t )( unsigned int ); // typedef void ( __cdecl * Free_t )( void * ); // typedef char * ( __cdecl * GetParameter_t )( long ); // #ifdef __cplusplus // extern "C" // #endif // _CRTIMP pchar_t __cdecl __unDName ( // pchar_t, // User supplied buffer (or NULL) // pcchar_t, // Input decorated name // int, // Maximum length of user buffer // Alloc_t, // Address of heap allocator // Free_t, // Address of heap deallocator // unsigned short // Feature disable flags // ); // #ifdef __cplusplus // extern "C" // #endif // _CRTIMP pchar_t __cdecl __unDNameEx ( // pchar_t, // User supplied buffer (or NULL) // pcchar_t, // Input decorated name // int, // Maximum length of user buffer // Alloc_t, // Address of heap allocator // Free_t, // Address of heap deallocator // GetParameter_t, // Function to get any template parameters // unsigned long // Feature disable flags // ); // /* // * The user may provide a buffer into which the undecorated declaration // * is to be placed, in which case, the length field must be specified. // * The length is the maximum number of characters (including the terminating // * NULL character) which may be written into the user buffer. // * // * If the output buffer is NULL, the length field is ignored, and the // * undecorator will allocate a buffer exactly large enough to hold the // * resulting declaration. It is the users responsibility to deallocate // * this buffer. // * // * The user may also supply the allocator and deallocator functions if // * they wish. If they do, then all heap actions performed by the routine // * will use the provided heap functions. // * // * If the allocator address is NULL, then the routine will default to using // * the standard allocator and deallocator functions, 'malloc' and 'free'. // * // * If an error occurs internally, then the routine will return NULL. If // * it was successful, it will return the buffer address provided by the // * user, or the address of the buffer allocated on their behalf, if they // * specified a NULL buffer address. // * // * If a given name does not have a valid undecoration, the original name // * is returned in the output buffer. // * // * Fine selection of a number of undecorator attributes is possible, by // * specifying flags (bit-fields) to disable the production of parts of the // * complete declaration. The flags may be OR'ed together to select multiple // * disabling of selected fields. The fields and flags are as follows :- // */ // #define UNDNAME_COMPLETE (0x0000) // Enable full undecoration // #define UNDNAME_NO_LEADING_UNDERSCORES (0x0001) // Remove leading underscores from MS extended keywords // #define UNDNAME_NO_MS_KEYWORDS (0x0002) // Disable expansion of MS extended keywords // #define UNDNAME_NO_FUNCTION_RETURNS (0x0004) // Disable expansion of return type for primary declaration // #define UNDNAME_NO_ALLOCATION_MODEL (0x0008) // Disable expansion of the declaration model // #define UNDNAME_NO_ALLOCATION_LANGUAGE (0x0010) // Disable expansion of the declaration language specifier // #define UNDNAME_NO_MS_THISTYPE (0x0020) /* NYI */ // Disable expansion of MS keywords on the 'this' type for primary declaration // #define UNDNAME_NO_CV_THISTYPE (0x0040) /* NYI */ // Disable expansion of CV modifiers on the 'this' type for primary declaration // #define UNDNAME_NO_THISTYPE (0x0060) // Disable all modifiers on the 'this' type // #define UNDNAME_NO_ACCESS_SPECIFIERS (0x0080) // Disable expansion of access specifiers for members // #define UNDNAME_NO_THROW_SIGNATURES (0x0100) // Disable expansion of 'throw-signatures' for functions and pointers to functions // #define UNDNAME_NO_MEMBER_TYPE (0x0200) // Disable expansion of 'static' or 'virtual'ness of members // #define UNDNAME_NO_RETURN_UDT_MODEL (0x0400) // Disable expansion of MS model for UDT returns // #define UNDNAME_32_BIT_DECODE (0x0800) // Undecorate 32-bit decorated names // #define UNDNAME_NAME_ONLY (0x1000) // Crack only the name for primary declaration; // // return just [scope::]name. Does expand template params // #define UNDNAME_TYPE_ONLY (0x2000) // Input is just a type encoding; compose an abstract declarator // #define UNDNAME_HAVE_PARAMETERS (0x4000) // The real templates parameters are available // #define UNDNAME_NO_ECSU (0x8000) // Suppress enum/class/struct/union // #define UNDNAME_NO_IDENT_CHAR_CHECK (0x10000) // Suppress check for IsValidIdentChar ================================================ FILE: Sysmon/undname.idl ================================================ import "oaidl.idl"; import "ocidl.idl"; // // Copyright (c) Microsoft Corporation. All rights reserved. // // // Use of this source code is subject to the terms of your Microsoft Windows CE // Source Alliance Program license form. If you did not accept the terms of // such a license, you are not authorized to use this source code. // /* * This module contains the definitions for the inline functions used by the * name undecorator. It is intended that this file should be included * somewhere in the source file for the undecorator to maximise the chance * that they will be truly inlined. */ // The following class is a special node class, used in the implementation // of the internal chaining mechanism of the 'DName's // class charNode; // class pcharNode; // class pDNameNode; // class DNameStatusNode; // #if ( NO_VIRTUAL ) // enum NodeType // { // charNode_t, // pcharNode_t, // pDNameNode_t, // DNameStatusNode_t // }; // #endif // NO_VIRTUAL // class DNameNode // { // private: // #if NO_VIRTUAL // NodeType typeIndex; // #endif // NO_VIRTUAL // DNameNode * next; // protected: // #if ( !NO_VIRTUAL ) // __near DNameNode (); // #else // } elif NO_VIRTUAL { // __near DNameNode ( NodeType ); // #endif // NO_VIRTUAL // __near DNameNode ( const DNameNode & ); // public: // virtual int __near length () const PURE; // virtual char __near getLastChar () const PURE; // virtual pchar_t __near getString ( pchar_t, int ) const PURE; // DNameNode * __near clone (); // DNameNode * __near nextNode () const; // DNameNode & __near operator += ( DNameNode * ); // }; // class charNode : public DNameNode // { // private: // char me; // public: // __near charNode ( char ); // virtual int __near length () const; // virtual char __near getLastChar () const; // virtual pchar_t __near getString ( pchar_t, int ) const; // }; // class pcharNode : public DNameNode // { // private: // pchar_t me; // int myLen; // public: // __near pcharNode ( pcchar_t, int = 0 ); // virtual int __near length () const; // virtual char __near getLastChar () const; // virtual pchar_t __near getString ( pchar_t, int ) const; // }; // class pDNameNode : public DNameNode // { // private: // DName * me; // public: // __near pDNameNode ( DName * ); // virtual int __near length () const; // virtual char __near getLastChar () const; // virtual pchar_t __near getString ( pchar_t, int ) const; // }; // class DNameStatusNode : public DNameNode // { // private: // #define TruncationMessage (" ?? ") // #define TruncationMessageLength (4) // DNameStatus me; // int myLen; // public: // __near DNameStatusNode ( DNameStatus ); // virtual int __near length () const; // virtual char __near getLastChar () const; // virtual pchar_t __near getString ( pchar_t, int ) const; // }; // // Memory allocation functions // inline void __far * __near __pascal operator new ( unsigned int sz, HeapManager &, int noBuffer ) // { return heap.getMemory ( sz, noBuffer ); } // void __far * __near HeapManager::getMemory ( unsigned int sz, int noBuffer ) // { // // Align the allocation on an appropriate boundary // sz = (( sz + PACK_SIZE-1 ) & ~(PACK_SIZE-1) ); // if ( noBuffer ) // return ( *pOpNew )( sz ); // else // { // // Handler a potential request for no space // if ( !sz ) // sz = 1; // if ( blockLeft < sz ) // { // // Is the request greater than the largest buffer size ? // if ( sz > memBlockSize ) // return 0; // If it is, there is nothing we can do // // Allocate a new block // Block * pNewBlock = rnew Block; // // Did the allocation succeed ? If so connect it up // if ( pNewBlock ) // { // // Handle the initial state // if ( tail ) // tail = tail->next = pNewBlock; // else // head = tail = pNewBlock; // // Compute the remaining space // blockLeft = memBlockSize - sz; // } // End of IF then // else // return 0; // Oh-oh! Memory allocation failure // } // End of IF then // else // blockLeft -= sz; // Deduct the allocated amount // // And return the buffer address // return &( tail->memBlock[ blockLeft ]); // } // End of IF else // } // End of "HeapManager" FUNCTION "getMemory(unsigned int,int)" // // Friend functions of 'DName' // inline DName __near __pascal operator + ( char c, const DName & rd ) // { return DName ( c ) + rd; } // inline DName __near __pascal operator + ( DNameStatus st, const DName & rd ) // { return DName ( st ) + rd; } // inline DName __near __pascal operator + ( pcchar_t s, const DName & rd ) // { return DName ( s ) + rd; } // // The 'DName' constructors // inline __near DName::DName () { node = 0; stat = DN_valid; isIndir = 0; isAUDC = 0; isAUDTThunk = 0; NoTE = 0; } // inline __near DName::DName ( DNameNode * pd ) { node = pd; stat = DN_valid; isIndir = 0; isAUDC = 0; isAUDTThunk = 0; NoTE = 0; } // __near DName::DName ( char c ) // { // stat = DN_valid; // isIndir = 0; // isAUDC = 0; // isAUDTThunk = 0; // node = 0; // NoTE = 0; // // The NULL character is boring, do not copy // if ( c ) // doPchar ( &c, 1 ); // } // End of "DName" CONSTRUCTOR '(char)' // #if 1 // inline __near DName::DName ( const DName & rd ) // { // stat = rd.stat; // isIndir = rd.isIndir; // isAUDC = rd.isAUDC; // isAUDTThunk = rd.isAUDTThunk; // node = rd.node; // NoTE = rd.NoTE; // } // End of "DName" CONSTRUCTOR '(const DName&)' // #endif // __near DName::DName ( DName * pd ) // { // if ( pd ) // { // node = gnew pDNameNode ( pd ); // stat = ( node ? DN_valid : DN_error ); // } // End of IF else // else // { // stat = DN_valid; // node = 0; // } // End of IF else // isIndir = 0; // isAUDC = 0; // isAUDTThunk = 0; // NoTE = 0; // } // End of "DName" CONSTRUCTOR '( DName* )' // __near DName::DName ( pcchar_t s ) // { // stat = DN_valid; // node = 0; // isIndir = 0; // isAUDC = 0; // isAUDTThunk = 0; // NoTE = 0; // if ( s ) // doPchar ( s, strlen ( s )); // } // End of "DName" CONSTRUCTOR '(pcchar_t)' // __near DName::DName ( pcchar_t & name, char terminator ) // { // stat = DN_valid; // isIndir = 0; // isAUDC = 0; // isAUDTThunk = 0; // node = 0; // NoTE = 0; // // Is there a string ? // if ( name ) // if ( *name ) // { // int len = 0; // // How long is the string ? // for ( pcchar_t s = name; *name && ( *name != terminator ); name++ ) // if ( isValidIdentChar ( *name ) || UnDecorator::doNoIdentCharCheck () ) // len++; // else // { // stat = DN_invalid; // return; // } // End of IF else // // Copy the name string fragment // doPchar ( s, len ); // // Now gobble the terminator if present, handle error conditions // if ( *name ) // { // if ( *name++ != terminator ) // { // stat = DN_error; // node = 0; // } // End of IF then // else // stat = DN_valid; // } // End of IF then // elif ( status () == DN_valid ) // stat = DN_truncated; // } // End of IF then // else // stat = DN_truncated; // else // stat = DN_invalid; // } // End of "DName" CONSTRUCTOR '(pcchar_t&,char)' // __near DName::DName ( unsigned long num ) // { // char buf[ 11 ]; // char * pBuf = buf + 10; // stat = DN_valid; // node = 0; // isIndir = 0; // isAUDC = 0; // isAUDTThunk = 0; // NoTE = 0; // // Essentially, 'ultoa ( num, buf, 10 )' :- // *pBuf = 0; // do // { // *( --pBuf ) = (char)(( num % 10 ) + '0' ); // num /= 10UL; // } while ( num ); // doPchar ( pBuf, ( 10 - (int) ( pBuf - buf ))); // } // End of "DName" CONSTRUCTOR '(unsigned long)' // __near DName::DName ( DNameStatus st ) // { // stat = ((( st == DN_invalid ) || ( st == DN_error )) ? st : DN_valid ); // node = gnew DNameStatusNode ( st ); // isIndir = 0; // isAUDC = 0; // isAUDTThunk = 0; // NoTE = 0; // if ( !node ) // stat = DN_error; // } // End of "DName" CONSTRUCTOR '(DNameStatus)' // // Now the member functions for 'DName' // int __near DName::isValid () const { return (( status () == DN_valid ) || ( status () == DN_truncated )); } // int __near DName::isEmpty () const { return (( node == 0 ) || !isValid ()); } // inline DNameStatus __near DName::status () const { return (DNameStatus)stat; } // The cast is to keep Glockenspiel quiet // inline DName & __near DName::setPtrRef () { isIndir = 1; return *this; } // inline int __near DName::isPtrRef () const { return isIndir; } // inline int __near DName::isUDC () const { return ( !isEmpty () && isAUDC ); } // inline void __near DName::setIsUDC () { if ( !isEmpty ()) isAUDC = TRUE; } // inline int __near DName::isUDTThunk () const { return ( !isEmpty () && isAUDTThunk ); } // inline void __near DName::setIsUDTThunk () { if ( !isEmpty ()) isAUDTThunk = TRUE; } // inline int DName::isNoTE () const { return NoTE; } // inline void DName::setIsNoTE () { NoTE = TRUE; } // int __near DName::length () const // { // int len = 0; // if ( !isEmpty ()) // for ( DNameNode * pNode = node; pNode; pNode = pNode->nextNode ()) // len += pNode->length (); // return len; // } // End of "DName" FUNCTION "length" // char __near DName::getLastChar () const // { // DNameNode * pLast = 0; // if ( !isEmpty ()) // for ( DNameNode * pNode = node; pNode; pNode = pNode->nextNode ()) // if ( pNode->length () != 0 ) // pLast = pNode; // return pLast != 0 ? pLast->getLastChar () : ''; // } // End of "DName" FUNCTION "getLastChar" // pchar_t __near DName::getString ( pchar_t buf, int max ) const // { // if ( !isEmpty ()) // { // // Does the caller want a buffer allocated ? // if ( !buf ) // { // max = length () + 1; // buf = gnew char[ max ]; // Get a buffer big enough // } // End of IF then // // If memory allocation failure, then return no buffer // if ( buf ) // { // // Now, go through the process of filling the buffer (until max is reached) // int curLen = max; // DNameNode * curNode = node; // pchar_t curBuf = buf; // while ( curNode && ( curLen > 0 )) // { // int fragLen = curNode->length (); // pchar_t fragBuf = 0; // // Skip empty nodes // if ( fragLen ) // { // // Handle buffer overflow // if (( curLen - fragLen ) < 0 ) // fragLen = curLen; // // Now copy 'len' number of bytes of the piece to the buffer // fragBuf = curNode->getString ( curBuf, fragLen ); // // Should never happen, but handle it anyway // if ( fragBuf ) // { // // Update string position // curLen -= fragLen; // curBuf += fragLen; // } // End of IF // } // End of IF // // Move on to the next name fragment // curNode = curNode->nextNode (); // } // End of WHILE // *curBuf = 0; // Always NULL terminate the resulting string // } // End of IF // } // End of IF then // elif ( buf ) // *buf = 0; // // Return the buffer // return buf; // } // End of "DName" FUNCTION "getString(pchar_t,int)" // DName __near DName::operator + ( char ch ) const // { // DName local ( *this ); // if ( local.isEmpty ()) // local = ch; // else // local += ch; // // And return the newly formed 'DName' // return local; // } // End of "DName" OPERATOR "+(char)" // DName __near DName::operator + ( pcchar_t str ) const // { // DName local ( *this ); // if ( local.isEmpty ()) // local = str; // else // local += str; // // And return the newly formed 'DName' // return local; // } // End of "DName" OPERATOR "+(pcchar_t)" // DName __near DName::operator + ( const DName & rd ) const // { // DName local ( *this ); // if ( local.isEmpty ()) // local = rd; // elif ( rd.isEmpty ()) // local += rd.status (); // else // local += rd; // // And return the newly formed 'DName' // return local; // } // End of "DName" OPERATOR "+(const DName&)" // DName __near DName::operator + ( DName * pd ) const // { // DName local ( *this ); // if ( local.isEmpty ()) // local = pd; // else // local += pd; // // And return the newly formed 'DName' // return local; // } // End of "DName" OPERATOR "+(DName*)" // DName __near DName::operator + ( DNameStatus st ) const // { // DName local ( *this ); // if ( local.isEmpty ()) // local = st; // else // local += st; // // And return the newly formed 'DName' // return local; // } // End of "DName" OPERATOR "+(DNameStatus)" // DName & __near DName::operator += ( char ch ) // { // if ( ch ) // if ( isEmpty ()) // *this = ch; // else // { // node = node->clone (); // if ( node ) // *node += gnew charNode ( ch ); // else // stat = DN_error; // } // End of IF // // And return self // return *this; // } // End of "DName" OPERATOR "+=(char)" // DName & __near DName::operator += ( pcchar_t str ) // { // if ( str && *str ) // if ( isEmpty ()) // *this = str; // else // { // node = node->clone (); // if ( node ) // *node += gnew pcharNode ( str ); // else // stat = DN_error; // } // End of IF // // And return self // return *this; // } // End of "DName" OPERATOR "+=(pcchar_t)" // DName & __near DName::operator += ( const DName & rd ) // { // if ( rd.isEmpty ()) // *this += rd.status (); // else // if ( isEmpty ()) // *this = rd; // else // { // node = node->clone (); // if ( node ) // *node += rd.node; // else // stat = DN_error; // } // End of IF // // And return self // return *this; // } // End of "DName" OPERATOR "+=(const DName&)" // DName & __near DName::operator += ( DName * pd ) // { // if ( pd ) // if ( isEmpty ()) // *this = pd; // elif (( pd->status () == DN_valid ) || ( pd->status () == DN_truncated )) // { // DNameNode * pNew = gnew pDNameNode ( pd ); // if ( pNew ) // { // node = node->clone (); // if ( node ) // *node += pNew; // } // End of IF then // else // node = 0; // if ( !node ) // stat = DN_error; // } // End of IF then // else // *this += pd->status (); // // And return self // return *this; // } // End of "DName" OPERATOR "+=(DName*)" // DName & __near DName::operator += ( DNameStatus st ) // { // if ( isEmpty () || (( st == DN_invalid ) || ( st == DN_error ))) // *this = st; // else // { // DNameNode * pNew = gnew DNameStatusNode ( st ); // if ( pNew ) // { // node = node->clone (); // if ( node ) // *node += pNew; // } // End of IF then // else // node = 0; // if ( !node ) // stat = DN_error; // } // End of IF else // // Return self // return *this; // } // End of "DName" OPERATOR "+=(DNameStatus)" // DName & __near DName::operator |= ( const DName & rd ) // { // // Attenuate the error status. Always becomes worse. Don't propogate truncation // if (( status () != DN_error ) && !rd.isValid ()) // stat = rd.status (); // // And return self // return *this; // } // End of "DName" OPERATOR '|=(const DName&)' // DName & __near DName::operator = ( char ch ) // { // isIndir = 0; // isAUDC = 0; // isAUDTThunk = 0; // doPchar ( &ch, 1 ); // return *this; // } // End of "DName" OPERATOR '=(char)' // DName & __near DName::operator = ( pcchar_t str ) // { // isIndir = 0; // isAUDC = 0; // isAUDTThunk = 0; // doPchar ( str, strlen ( str )); // // And return self // return *this; // } // End of "DName" OPERATOR '=(pcchar_t)' // DName & __near DName::operator = ( const DName & rd ) // { // if (( status () == DN_valid ) || ( status () == DN_truncated )) // { // stat = rd.stat; // isIndir = rd.isIndir; // isAUDC = rd.isAUDC; // isAUDTThunk = rd.isAUDTThunk; // node = rd.node; // } // End of IF // // And return self // return *this; // } // End of "DName" OPERATOR '=(const DName&)' // DName & __near DName::operator = ( DName * pd ) // { // if (( status () == DN_valid ) || ( status () == DN_truncated )) // if ( pd ) // { // isIndir = 0; // isAUDC = 0; // isAUDTThunk = 0; // node = gnew pDNameNode ( pd ); // if ( !node ) // stat = DN_error; // } // End of IF then // else // *this = DN_error; // // And return self // return *this; // } // End of "DName" OPERATOR '=(DName*)' // DName & __near DName::operator = ( DNameStatus st ) // { // if (( st == DN_invalid ) || ( st == DN_error )) // { // node = 0; // if ( status () != DN_error ) // stat = st; // } // End of IF then // elif (( status () == DN_valid ) || ( status () == DN_truncated )) // { // isIndir = 0; // isAUDC = 0; // isAUDTThunk = 0; // node = gnew DNameStatusNode ( st ); // if ( !node ) // stat = DN_error; // } // End of ELIF then // // And return self // return *this; // } // End of "DName" OPERATOR '=(DNameStatus)' // // Private implementation functions for 'DName' // void __near DName::doPchar ( pcchar_t str, int len ) // { // if ( !(( status () == DN_invalid ) || ( status () == DN_error ))) // if ( node ) // *this = DN_error; // elif ( str && len ) // { // // Allocate as economically as possible // switch ( len ) // { // case 0: // stat = DN_error; // break; // case 1: // node = gnew charNode ( *str ); // if ( !node ) // stat = DN_error; // break; // default: // node = gnew pcharNode ( str, len ); // if ( !node ) // stat = DN_error; // break; // } // End of SWITCH // } // End of ELIF // else // stat = DN_invalid; // } // End of "DName" FUNCTION "doPchar(pcchar_t,int)" // // The member functions for the 'Replicator' // inline int __near Replicator::isFull () const { return ( index == 9 ); } // inline __near Replicator::Replicator () // : ErrorDName ( DN_error ), InvalidDName ( DN_invalid ) // { index = -1; } // Replicator & __near Replicator::operator += ( const DName & rd ) // { // if ( !isFull () && !rd.isEmpty ()) // { // DName * pNew = gnew DName ( rd ); // // Don't update if failed // if ( pNew ) // dNameBuffer[ ++index ] = pNew; // } // End of IF // return *this; // } // End of "Replicator" OPERATOR '+=(const DName&)' // const DName & __near Replicator::operator [] ( int x ) const // { // if (( x < 0 ) || ( x > 9 )) // return ErrorDName; // elif (( index == -1 ) || ( x > index )) // return InvalidDName; // else // return *dNameBuffer[ x ]; // } // End of "Replicator" OPERATOR '[](int)' // // The member functions for the 'DNameNode' classes // #if ( !NO_VIRTUAL ) // __near DNameNode::DNameNode () // #else // } elif NO_VIRTUAL { // __near DNameNode::DNameNode ( NodeType ndTy ) // : typeIndex ( ndTy ) // #endif // NO_VIRTUAL // { next = 0; } // inline __near DNameNode::DNameNode ( const DNameNode & rd ) { next = (( rd.next ) ? rd.next->clone () : 0 ); } // inline DNameNode * __near DNameNode::nextNode () const { return next; } // DNameNode * __near DNameNode::clone () // { // return gnew pDNameNode ( gnew DName ( this )); // } // #if ( NO_VIRTUAL ) // int __near DNameNode::length () const // { // Pure function, should not be called // switch ( typeIndex ) // { // case charNode_t: // return ((charNode*)this )->length (); // case pcharNode_t: // return ((pcharNode*)this )->length (); // case pDNameNode_t: // return ((pDNameNode*)this )->length (); // case DNameStatusNode_t: // return ((DNameStatusNode*)this )->length (); // } // End of SWITCH // return 0; // } // int __near DNameNode::getLastChar () const // { // Pure function, should not be called // switch ( typeIndex ) // { // case charNode_t: // return ((charNode*)this )->getLastChar (); // case pcharNode_t: // return ((pcharNode*)this )->getLastChar (); // case pDNameNode_t: // return ((pDNameNode*)this )->getLastChar (); // case DNameStatusNode_t: // return ((DNameStatusNode*)this )->getLastChar (); // } // End of SWITCH // return 0; // } // pchar_t __near DNameNode::getString ( pchar_t s, int l ) const // { // Pure function, should not be called // switch ( typeIndex ) // { // case charNode_t: // return ((charNode*)this )->getString ( s, l ); // case pcharNode_t: // return ((pcharNode*)this )->getString ( s, l ); // case pDNameNode_t: // return ((pDNameNode*)this )->getString ( s, l ); // case DNameStatusNode_t: // return ((DNameStatusNode*)this )->getString ( s, l ); // } // End of SWITCH // return 0; // } // #endif // NO_VIRTUAL // DNameNode & __near DNameNode::operator += ( DNameNode * pNode ) // { // if ( pNode ) // { // if ( next ) // { // // Skip to the end of the chain // for ( DNameNode* pScan = next; pScan->next; pScan = pScan->next ) // ; // // And append the new node // pScan->next = pNode; // } // End of IF then // else // next = pNode; // } // End of IF // // And return self // return *this; // } // End of "DNameNode" OPERATOR '+=(DNameNode*)' // // The 'charNode' virtual functions // __near charNode::charNode ( char ch ) // #if ( NO_VIRTUAL ) // : DNameNode ( charNode_t ) // #endif // NO_VIRTUAL // { me = ch; } // inline int __near charNode::length () const { return 1; } // inline char __near charNode::getLastChar () const { return me; } // pchar_t __near charNode::getString ( pchar_t buf, int len ) const // { // if ( buf && len ) // *buf = me; // else // buf = 0; // // Now return the character // return buf; // } // End of "charNode" FUNCTION "getString(pchar_t,int)" // // The 'pcharNode' virtual functions // inline int __near pcharNode::length () const { return myLen; } // inline char __near pcharNode::getLastChar () const { return ( myLen ? me[ myLen - 1 ] : '' ); } // __near pcharNode::pcharNode ( pcchar_t str, int len ) // #if ( NO_VIRTUAL ) // : DNameNode ( pcharNode_t ) // #endif // NO_VIRTUAL // { // // Get length if not supplied // if ( !len && str ) // len = strlen ( str ); // // Allocate a new string buffer if valid state // if ( len && str ) // { // me = gnew char[ len ]; // myLen = len; // if ( me ) // strncpy ( me, str, len ); // } // End of IF then // else // { // me = 0; // myLen = 0; // } // End of IF else // } // End of "pcharNode" CONSTRUCTOR '(pcchar_t,int)' // pchar_t __near pcharNode::getString ( pchar_t buf, int len ) const // { // // Use the shorter of the two lengths (may not be NULL terminated) // if ( len > pcharNode::length ()) // len = pcharNode::length (); // // Do the copy as appropriate // return (( me && buf && len ) ? strncpy ( buf, me, len ) : 0 ); // } // End of "pcharNode" FUNCTION "getString(pchar_t,int)" // // The 'pDNameNode' virtual functions // __near pDNameNode::pDNameNode ( DName * pName ) // #if ( NO_VIRTUAL ) // : DNameNode ( pDNameNode_t ) // #endif // NO_VIRTUAL // { me = (( pName && (( pName->status () == DN_invalid ) || ( pName->status () == DN_error ))) ? 0 : pName ); } // inline int __near pDNameNode::length () const { return ( me ? me->length () : 0 ); } // inline char __near pDNameNode::getLastChar () const { return ( me ? me->getLastChar () : '' ); } // pchar_t __near pDNameNode::getString ( pchar_t buf, int len ) const // { return (( me && buf && len ) ? me->getString ( buf, len ) : 0 ); } // // The 'DNameStatusNode' virtual functions // __near DNameStatusNode::DNameStatusNode ( DNameStatus stat ) // #if ( NO_VIRTUAL ) // : DNameNode ( DNameStatusNode_t ) // #endif // NO_VIRTUAL // { me = stat; myLen = (( me == DN_truncated ) ? TruncationMessageLength : 0 ); } // inline int __near DNameStatusNode::length () const { return myLen; } // inline char __near DNameStatusNode::getLastChar () const // { return (( me == DN_truncated ) ? TruncationMessage[ TruncationMessageLength - 1 ] : '' ); } // pchar_t __near DNameStatusNode::getString ( pchar_t buf, int len ) const // { // // Use the shorter of the two lengths (may not be NULL terminated) // if ( len > DNameStatusNode::length ()) // len = DNameStatusNode::length (); // // Do the copy as appropriate // return ((( me == DN_truncated ) && buf && len ) ? strncpy ( buf, TruncationMessage, len ) : 0 ); // } // End of "DNameStatusNode" FUNCTION "getString(pchar_t,int)" ================================================ FILE: Sysmon.sln ================================================  Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Sysmon", "Sysmon\Sysmon.vcxproj", "{E64CC626-B5DB-47C9-93DD-D14F2F60B6C6}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Sysmon.sys", "Sysmon.sys\Sysmon.sys.vcxproj", "{E179CA60-36AC-4DCC-8B87-06214F32DD0B}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {E64CC626-B5DB-47C9-93DD-D14F2F60B6C6}.Debug|Win32.ActiveCfg = Debug|Win32 {E64CC626-B5DB-47C9-93DD-D14F2F60B6C6}.Debug|Win32.Build.0 = Debug|Win32 {E64CC626-B5DB-47C9-93DD-D14F2F60B6C6}.Debug|x64.ActiveCfg = Debug|x64 {E64CC626-B5DB-47C9-93DD-D14F2F60B6C6}.Debug|x64.Build.0 = Debug|x64 {E64CC626-B5DB-47C9-93DD-D14F2F60B6C6}.Release|Win32.ActiveCfg = Release|Win32 {E64CC626-B5DB-47C9-93DD-D14F2F60B6C6}.Release|Win32.Build.0 = Release|Win32 {E64CC626-B5DB-47C9-93DD-D14F2F60B6C6}.Release|x64.ActiveCfg = Release|x64 {E64CC626-B5DB-47C9-93DD-D14F2F60B6C6}.Release|x64.Build.0 = Release|x64 {E179CA60-36AC-4DCC-8B87-06214F32DD0B}.Debug|Win32.ActiveCfg = Debug|Win32 {E179CA60-36AC-4DCC-8B87-06214F32DD0B}.Debug|Win32.Build.0 = Debug|Win32 {E179CA60-36AC-4DCC-8B87-06214F32DD0B}.Debug|x64.ActiveCfg = Debug|x64 {E179CA60-36AC-4DCC-8B87-06214F32DD0B}.Debug|x64.Build.0 = Debug|x64 {E179CA60-36AC-4DCC-8B87-06214F32DD0B}.Release|Win32.ActiveCfg = Release|Win32 {E179CA60-36AC-4DCC-8B87-06214F32DD0B}.Release|Win32.Build.0 = Release|Win32 {E179CA60-36AC-4DCC-8B87-06214F32DD0B}.Release|x64.ActiveCfg = Release|x64 {E179CA60-36AC-4DCC-8B87-06214F32DD0B}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: Sysmon.sys/CDeviceExtension.cpp ================================================ #include "CDeviceExtension.h" /**********************************************************************************/ #pragma LOCKEDCODE CDeviceExtension::CDeviceExtension(void) { } /**********************************************************************************/ #pragma LOCKEDCODE CDeviceExtension::~CDeviceExtension(void) { } /**********************************************************************************/ #pragma PAGEDCODE CDeviceExtension::operator PIO_CSQ() { return &mCsq; } /**********************************************************************************/ #pragma PAGEDCODE CDeviceExtension::operator PRKEVENT() { return &mFileEvent; } /**********************************************************************************/ #pragma INITCODE void CDeviceExtension::Init() { KeInitializeEvent( &mFileEvent, SynchronizationEvent, 0); } ================================================ FILE: Sysmon.sys/CDeviceExtension.h ================================================ #ifndef _CDeviceExtension_h #define _CDeviceExtension_h #include class CDeviceExtension { public: CDeviceExtension(void); virtual ~CDeviceExtension(void); operator PIO_CSQ(); operator PRKEVENT(); void Init(); private: IO_CSQ mCsq; KEVENT mFileEvent; }; #endif ================================================ FILE: Sysmon.sys/CDriverEntry.cpp ================================================ #include "CDriverEntry.h" #include #include "CErrorStatus.h" #include "CUnicodeString.h" #include "CString.h" #include "CDriverDispatch.h" #include "CSysmonDispatchEngine.h" #include "CDeviceExtension.h" #include CDriverEntry CDriverEntry::_Instance; /**********************************************************************************/ #pragma LOCKEDCODE CDriverEntry::CDriverEntry(void) :mIsSupportFlt(FALSE) { } /**********************************************************************************/ #pragma LOCKEDCODE CDriverEntry::~CDriverEntry(void) { } /**********************************************************************************/ #pragma LOCKEDCODE CDriverEntry& CDriverEntry::Instance() { return _Instance; } /**********************************************************************************/ #pragma LOCKEDCODE void CDriverEntry::PsGetVersion() { mSystemVersion.PsGetVersion(); } /**********************************************************************************/ #pragma LOCKEDCODE BOOL CDriverEntry::IsSupportFlt() { CVersion OsVersion; OsVersion.GetOsVersion(); mIsSupportFlt = ( OsVersion.GetMajorVersion() > 6 || ( OsVersion.GetMajorVersion() == 6 && OsVersion.GetMinorVersion() >= 2)); return mIsSupportFlt; } /**********************************************************************************/ #pragma INITCODE NTSTATUS CDriverEntry::Init( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { CErrorStatus Status = STATUS_UNSUCCESSFUL; CallGlobalConstructors(); CStackStringW<256> DeviceName; CStackStringW<256> DosDeviceName; CDriverDispatch DriverDispatch; CUnicodeString DevicePath = RegistryPath; BOOL IsSupportFlt = FALSE; CDriverEntry::Instance().PsGetVersion(); DeviceName[0] = '\\'; DeviceName[1] = 'D'; DeviceName[2] = 'e'; DeviceName[3] = 'v'; DeviceName[4] = 'i'; DeviceName[5] = 'c'; DeviceName[6] = 'e'; DeviceName[7] = '\\'; DeviceName[8] = '\\'; DosDeviceName[0] = '\\'; DosDeviceName[1] = 'D'; DosDeviceName[2] = 'o'; DosDeviceName[3] = 's'; DosDeviceName[4] = 'D'; DosDeviceName[5] = 'e'; DosDeviceName[6] = 'v'; DosDeviceName[7] = 'i'; DosDeviceName[8] = 'c'; DosDeviceName[9] = 'e'; DosDeviceName[10] = 's'; DosDeviceName[11] = '\\'; DosDeviceName[12] = '\\'; PWCHAR pEndPathName = &RegistryPath->Buffer[RegistryPath->Length/2]; do { if (pEndPathName == RegistryPath->Buffer) { if (pEndPathName[0] != '\\') { break; } } else { while (pEndPathName[0] != '\\') { pEndPathName--; if (pEndPathName == RegistryPath->Buffer) { break; } } } ++pEndPathName; } while (FALSE); ULONG LengthOfName = RegistryPath->Length - (pEndPathName - RegistryPath->Buffer); if (LengthOfName > 255) { LengthOfName = 255; } memcpy(&DeviceName[8], pEndPathName, LengthOfName); wcsncpy(&DosDeviceName[12], pEndPathName, LengthOfName); IsSupportFlt = CDriverEntry::Instance().IsSupportFlt(); DriverDispatch = DriverObject->MajorFunction; if (!DriverDispatch) { DriverDispatch[IRP_MJ_CREATE] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_CLOSE] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_DEVICE_CONTROL] = CSysmonDispatchEngine::SysmonDispatchIrp; if (!IsSupportFlt) { DriverDispatch[IRP_MJ_CREATE] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_CREATE_NAMED_PIPE] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_CLOSE] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_READ] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_WRITE] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_QUERY_INFORMATION] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_SET_INFORMATION] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_QUERY_EA] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_SET_EA] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_FLUSH_BUFFERS] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_QUERY_VOLUME_INFORMATION] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_SET_VOLUME_INFORMATION] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_DIRECTORY_CONTROL] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_FILE_SYSTEM_CONTROL] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_DEVICE_CONTROL] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_INTERNAL_DEVICE_CONTROL] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_SHUTDOWN] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_LOCK_CONTROL] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_CLEANUP] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_CREATE_MAILSLOT] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_QUERY_SECURITY] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_SET_SECURITY] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_POWER] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_SYSTEM_CONTROL] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_DEVICE_CHANGE] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_QUERY_QUOTA] = CSysmonDispatchEngine::SysmonDispatchIrp; DriverDispatch[IRP_MJ_SET_QUOTA] = CSysmonDispatchEngine::SysmonDispatchIrp; } } do { Status = CDriverEntry::Instance().InitIoDeice( DriverObject, DeviceName, DosDeviceName, sizeof(CDeviceExtension)); if (Status.IsNtSuccess()) { __try { CDeviceExtension* DeviceExtension = (CDeviceExtension*)CDriverEntry::Instance().Extension(); if (DeviceExtension) { CSysmonDispatchEngine::InitCsq(*DeviceExtension); DeviceExtension->Init(); } Status = CDriverEntry::Instance().InitMiniFlt(DriverObject); if (!Status.IsNtSuccess()) { CDriverEntry::Instance().DeleteDosLink(DosDeviceName); break; } } __except(EXCEPTION_CONTINUE_EXECUTION) { } } } while (FALSE); return Status; } /**********************************************************************************/ #pragma INITCODE CErrorStatus CDriverEntry::InitIoDeice( PDRIVER_OBJECT Driver, CStackStringW<256>& DeviceName, CStackStringW<256>& DosDeviceName, const UINT32 DeviceExtSize ) { return mDeviceObject.Init(Driver,DeviceName,DosDeviceName,DeviceExtSize); } /**********************************************************************************/ #pragma LOCKEDCODE void* CDriverEntry::Extension() { return mDeviceObject.DeviceExtension(); } /**********************************************************************************/ #pragma INITCODE CErrorStatus CDriverEntry::InitMiniFlt(PDRIVER_OBJECT DriverObj) { return mMiniFltFilter.Init(DriverObj); } /**********************************************************************************/ #pragma PAGEDCODE void CDriverEntry::DeleteDosLink(CStackStringW<256>& SymbolicLink) { mDeviceObject.DeleteSymbolicLink(SymbolicLink); } ================================================ FILE: Sysmon.sys/CDriverEntry.h ================================================ #ifndef _CDriverEntry_h #define _CDriverEntry_h #include "CVersion.h" #include #include "CReportRecord.h" #include "CDeviceObject.h" #include "CSysmonMiniFltFilter.h" #ifdef __cplusplus extern "C"{ #endif class CDriverEntry { public: CDriverEntry(void); ~CDriverEntry(void); public: static NTSTATUS NTAPI Init( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ); static CDriverEntry& Instance(); public: void PsGetVersion(); BOOL IsSupportFlt(); CErrorStatus InitIoDeice( PDRIVER_OBJECT Driver, CStackStringW<256>& DeviceName, CStackStringW<256>& DosDeviceName, const UINT32 DeviceExtSize ); void DeleteDosLink(CStackStringW<256>& SymbolicLink); void* Extension(); CErrorStatus InitMiniFlt(PDRIVER_OBJECT DriverObj); private: CVersion mSystemVersion; BOOL mIsSupportFlt; CReportSysmonRecord mReportSysmonRecord; CDeviceObject mDeviceObject; CSysmonMiniFltFilter mMiniFltFilter; private: static CDriverEntry _Instance; }; #ifdef __cplusplus }; #endif #endif ================================================ FILE: Sysmon.sys/CReportRecord.cpp ================================================ #include "CReportRecord.h" /**********************************************************************************/ #pragma LOCKEDCODE CSysmonRecord::CSysmonRecord() { } /**********************************************************************************/ #pragma LOCKEDCODE CSysmonRecord::~CSysmonRecord() { } /**********************************************************************************/ #pragma LOCKEDCODE CReportSysmonRecord::CReportSysmonRecord(void) { } /**********************************************************************************/ #pragma LOCKEDCODE CReportSysmonRecord::~CReportSysmonRecord(void) { } ================================================ FILE: Sysmon.sys/CReportRecord.h ================================================ #ifndef _CReportRecord_h #define _CReportRecord_h #include #include class CSysmonRecord { public: CSysmonRecord(); ~CSysmonRecord(); private: USHORT mType; }; class CReportSysmonRecord { public: CReportSysmonRecord(void); ~CReportSysmonRecord(void); private: CListEntry mReportRecord; }; #endif ================================================ FILE: Sysmon.sys/CSysmonControl.cpp ================================================ #include "CSysmonControl.h" /**********************************************************************************/ #pragma INITCODE CSysmonControl::CSysmonControl(void) { } /**********************************************************************************/ #pragma LOCKEDCODE CSysmonControl::~CSysmonControl(void) { } ================================================ FILE: Sysmon.sys/CSysmonControl.h ================================================ #ifndef _CSysmonControl_h #define _CSysmonControl_h class CSysmonControl { public: CSysmonControl(void); virtual ~CSysmonControl(void); }; #endif ================================================ FILE: Sysmon.sys/CSysmonDispatchEngine.cpp ================================================ #include "CSysmonDispatchEngine.h" #include #include #include #include #include "CSysmonioControl.h" #define FLT_CONTEXT(Context) (Sysmon_Flt_CompletionContext*)Context /**********************************************************************************/ #pragma LOCKEDCODE CSysmonDispatchEngine::CSysmonDispatchEngine(void) { } /**********************************************************************************/ #pragma LOCKEDCODE CSysmonDispatchEngine::~CSysmonDispatchEngine(void) { } /**********************************************************************************/ #pragma LOCKEDCODE NTSTATUS CSysmonDispatchEngine::SysmonDispatchIrp( PDEVICE_OBJECT DeviceObject, PIRP Irp) { CErrorStatus Status = STATUS_SUCCESS; CIoStackLocation IoStack; CIrp SysmonIrp(Irp); IoStack = SysmonIrp.StackLocation(); SysmonIrp.Information() = STATUS_SUCCESS; if (SysmonIrp.MajorFunction()) { if (SysmonIrp.MajorFunction() != IRP_MJ_DEVICE_CONTROL) { if ( SysmonIrp.MajorFunction() == IRP_MJ_CLEANUP ) { CDeviceExtension* Externsion = (CDeviceExtension*) SysmonIrp.FileObject()->DeviceObject->DeviceExtension; if (Externsion) { CIrp CsqIrp; do { if (CsqIrp ) { CsqIrp.Information() = STATUS_SUCCESS; CsqIrp.Complete(STATUS_CANCELLED,0); } CsqIrp = IoCsqRemoveNextIrp(*Externsion,IoStack.FileObject()); } while (CsqIrp != NULL); } } else { Status = STATUS_INVALID_DEVICE_REQUEST; } } else { //here is cope IRP_MJ_DEVICE_CONTROL } } else { SECURITY_SUBJECT_CONTEXT SubjectSecurityContext; PRIVILEGE_SET RequiredPrivileges; SeCaptureSubjectContext(&SubjectSecurityContext); RequiredPrivileges.PrivilegeCount = 1; RequiredPrivileges.Control = PRIVILEGE_SET_ALL_NECESSARY; RequiredPrivileges.Privilege[0].Luid.LowPart = 20; RequiredPrivileges.Privilege[0].Luid.HighPart = 0; RequiredPrivileges.Privilege[0].Attributes = 0; if(SePrivilegeCheck( &RequiredPrivileges, &SubjectSecurityContext, ExGetPreviousMode()) != TRUE) { Status = STATUS_ACCESS_DENIED; } SeReleaseSubjectContext(&SubjectSecurityContext); } if ( Status != STATUS_PENDING ) { SysmonIrp.Complete(Status,0);//IofCompleteRequest(v3, 0); } return Status; } /**********************************************************************************/ #pragma LOCKEDCODE NTSTATUS CSysmonDispatchEngine::SysmonFltPreOperation( PFLT_CALLBACK_DATA Data, PFLT_RELATED_OBJECTS FltObjects, PVOID *CompletionContext ) { CErrorStatus Status = STATUS_WAIT_1; LARGE_INTEGER FileCreateTime; Sysmon_Flt_CompletionContext* FltCompletionContext = FLT_CONTEXT(CompletionContext); FltCompletionContext->ContextValue = 0; do { USHORT FileObjType = CSysmonBase::SysmonIsNamedPipe(FltObjects); if (FileObjType == kFileObjFilePath) { Status = STATUS_SUCCESS; break; } else if (FileObjType == kFileObjNamedPipe ) { Status = STATUS_SUCCESS; break; } if (!IoGetTopLevelIrp()) { //ʾûģʽirp if (CSysmonBase::SysmonFileIsCommonName(Data)) { FltCompletionContext->ContextValue = 4; Status = STATUS_SUCCESS; break; } if ( Data->Iopb->MajorFunction == IRP_MJ_SET_INFORMATION) { // ļbasicInfo if ( Data->RequestorMode == UserMode && Data->Iopb->Parameters.SetFileInformation.FileInformationClass == FileBasicInformation && Data->Iopb->Parameters.SetFileInformation.Length >= sizeof(FILE_BASIC_INFORMATION) ) { FILE_BASIC_INFORMATION* pBaseInfo = (FILE_BASIC_INFORMATION *) Data->Iopb->Parameters.SetFileInformation.InfoBuffer; FileCreateTime.QuadPart = pBaseInfo->CreationTime.QuadPart; if ( pBaseInfo ) { if ( pBaseInfo->CreationTime.QuadPart ) { if ( (FileCreateTime.HighPart & FileCreateTime.LowPart) != -1 && (FileCreateTime.LowPart != -2 || FileCreateTime.HighPart != -1) && CSysmonBase::SysmonQueryFileFileAttributes(FltObjects) ) { // pReportEvent = SysmonCReateSetFileInfoReport( // FltObjects, // FileCreateTime->LowPart, // FileCreateTime->HighPart); // if ( pReportEvent ) // { // *CompletionContext = pReportEvent; // v3 = 0; // } } } } } } else if ( Data->Iopb->MajorFunction == IRP_MJ_CLEANUP ) { //if ( byte_10015C17 ) { PSysmon_Flt_Stream_Context FltContext = 0; if ( NT_SUCCESS(FltGetStreamContext( FltObjects->Instance, FltObjects->FileObject, (PFLT_CONTEXT*)&FltContext))) { if ( FltObjects->FileObject->FsContext2 == FltContext->FsContext2 ) { FltContext->FsContext2 = 0; // v9 = (struct _Sysmon_Report_Common_Header *)SysmonGetFileReportEventAndIsCalHash( // (PFLT_INSTANCE)FltObjects->Instance, // FltObjects->FileObject, // 1); // if ( v9 ) // SysmonReportEvent(v9); FltDeleteContext(FltContext); } FltReleaseContext(FltContext); } } } if ( !Data->Iopb->MajorFunction /*&& (byte_10015C2C || byte_10015C17)*/ ) { //if ( v3 ) { UCHAR CreateOption = (UCHAR)(((Data->Iopb->Parameters.Create.Options)>>24) & 0xFF); if ( CreateOption == FILE_SUPERSEDE || //½/ļ CreateOption == FILE_CREATE || //½ļ CreateOption == FILE_OVERWRITE || //ļ CreateOption == FILE_MAXIMUM_DISPOSITION || //򿪲/ļ CreateOption == FILE_OPEN_IF //Ѵļ ) { Status = STATUS_SUCCESS; FltCompletionContext->ContextValue = 5; } } } } } while (FALSE); return Status; } /**********************************************************************************/ #pragma LOCKEDCODE NTSTATUS CSysmonDispatchEngine::SysmonFltPostOperation( PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID CompletionContext, FLT_POST_OPERATION_FLAGS Flags ) { CErrorStatus Status = STATUS_SUCCESS; return Status; } /**********************************************************************************/ #pragma LOCKEDCODE void CSysmonDispatchEngine::SysmonIoCsqInsertIrp( PIO_CSQ Csq, PIRP Irp ) { PLIST_ENTRY ListHead = (PLIST_ENTRY)((UCHAR*)Csq - sizeof(IO_CSQ) - sizeof(LIST_ENTRY)); InsertTailList(ListHead,&Irp->Tail.Overlay.ListEntry); } /**********************************************************************************/ #pragma LOCKEDCODE void CSysmonDispatchEngine::SysmonIoCsqRemoveIrp( PIO_CSQ Csq, PIRP Irp ) { RemoveEntryList(&Irp->Tail.Overlay.ListEntry); } /**********************************************************************************/ #pragma LOCKEDCODE PIRP CSysmonDispatchEngine::SysmonIoCsqPeekNextIrp( PIO_CSQ Csq, PIRP Irp, PVOID PeekContext ) { PLIST_ENTRY ListHead = (PLIST_ENTRY)((UCHAR*)Csq - sizeof(IO_CSQ) - sizeof(LIST_ENTRY)); LIST_ENTRY* Flink = NULL; if (Irp) { Flink = Irp->Tail.Overlay.ListEntry.Flink; } else { Flink = ListHead->Flink; } if (Flink == ListHead) { return 0; } while ( PeekContext && Flink[1].Flink[3].Flink != PeekContext ) { Flink = Flink->Flink; if ( Flink == ListHead ) return 0; } return Irp; } /**********************************************************************************/ #pragma LOCKEDCODE void CSysmonDispatchEngine::SysmonIoCsqAcquireLock( PIO_CSQ Csq, PKIRQL Irql ) { ExAcquireFastMutex((PFAST_MUTEX)&Csq[-1]); } /**********************************************************************************/ #pragma LOCKEDCODE void CSysmonDispatchEngine::SysmonIoCsqReleaseLock( PIO_CSQ Csq, KIRQL Irql ) { ExReleaseFastMutex((PFAST_MUTEX)&Csq[-1]); } /**********************************************************************************/ #pragma LOCKEDCODE void CSysmonDispatchEngine::SysmonIoCsqCompleteCanceledIrp( PIO_CSQ Csq, PIRP Irp ) { Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Information = 0; IofCompleteRequest(Irp, 0); } /**********************************************************************************/ #pragma INITCODE void CSysmonDispatchEngine::InitCsq(CDeviceExtension& DevExt) { ::IoCsqInitialize( DevExt, (PIO_CSQ_INSERT_IRP)SysmonIoCsqInsertIrp, (PIO_CSQ_REMOVE_IRP)SysmonIoCsqRemoveIrp, (PIO_CSQ_PEEK_NEXT_IRP)SysmonIoCsqPeekNextIrp, (PIO_CSQ_ACQUIRE_LOCK)SysmonIoCsqAcquireLock, (PIO_CSQ_RELEASE_LOCK)SysmonIoCsqReleaseLock, (PIO_CSQ_COMPLETE_CANCELED_IRP)SysmonIoCsqCompleteCanceledIrp); } ================================================ FILE: Sysmon.sys/CSysmonDispatchEngine.h ================================================ #ifndef _CSysmonDispatchEngine_h #define _CSysmonDispatchEngine_h #include #include "CDeviceExtension.h" #include class CSysmonDispatchEngine { public: CSysmonDispatchEngine(void); ~CSysmonDispatchEngine(void); public: static NTSTATUS NTAPI SysmonDispatchIrp( PDEVICE_OBJECT DeviceObject, PIRP Irp); static NTSTATUS NTAPI SysmonFltPreOperation ( PFLT_CALLBACK_DATA Data, PFLT_RELATED_OBJECTS FltObjects, PVOID *CompletionContext ); static NTSTATUS NTAPI SysmonFltPostOperation ( PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID CompletionContext, FLT_POST_OPERATION_FLAGS Flags ); static void NTAPI SysmonIoCsqInsertIrp( PIO_CSQ Csq, PIRP Irp ); static void NTAPI SysmonIoCsqRemoveIrp( PIO_CSQ Csq, PIRP Irp ); static PIRP NTAPI SysmonIoCsqPeekNextIrp( PIO_CSQ Csq, PIRP Irp, PVOID PeekContext ); static void NTAPI SysmonIoCsqAcquireLock( PIO_CSQ Csq, PKIRQL Irql ); static void NTAPI SysmonIoCsqReleaseLock( PIO_CSQ Csq, KIRQL Irql ); static void NTAPI SysmonIoCsqCompleteCanceledIrp( PIO_CSQ Csq, PIRP Irp ); static void InitCsq(CDeviceExtension& DevExt); }; #endif ================================================ FILE: Sysmon.sys/CSysmonIoControl.h ================================================ #ifndef _CSysmonControl_h #define _CSysmonControl_h typedef enum _Base_Sysmon_FileObj_Type { kFileObjErrorType = 0, kFileObjFilePath = 1, kFileObjNamedPipe = 2, }Base_Sysmon_FileObj_Type; typedef struct _Sysmon_Flt_CompletionContext { union { ULONG ContextValue; PVOID* ReportEvent; }; }Sysmon_Flt_CompletionContext; typedef struct _Sysmon_Flt_Stream_Context { PVOID* FsContext2; }Sysmon_Flt_Stream_Context,*PSysmon_Flt_Stream_Context; #endif ================================================ FILE: Sysmon.sys/CSysmonMiniFltFilter.cpp ================================================ #include "CSysmonMiniFltFilter.h" #include "CSysmonDispatchEngine.h" #include "CSysmonIoControl.h" #define FLTPOST(Fn) (PFLT_POST_OPERATION_CALLBACK)CSysmonDispatchEngine::Fn #define FLTPRE(Fn) (PFLT_PRE_OPERATION_CALLBACK)CSysmonDispatchEngine::Fn CSysmonMiniFltFilter::CSysmonMiniFltFilter(void) { } CSysmonMiniFltFilter::~CSysmonMiniFltFilter(void) { } /**********************************************************************************/ #pragma INITCODE CErrorStatus CSysmonMiniFltFilter::Init(PDRIVER_OBJECT DriverObj) { CErrorStatus Status; RegisterCallback( kFilterUnloadCallback, CSysmonMiniFltFilter::FilterUnloadCallback); RegisterCallback( kInstanceSetupCallbac, CSysmonMiniFltFilter::InstanceSetupCallback); RegisterCallback( kInstanceQueryTeardowCallback, CSysmonMiniFltFilter::InstanceQueryTeardownCallback); RegisterContext( 0, FLT_STREAMHANDLE_CONTEXT, 2, 'csyS'); RegisterContext( 1, FLT_STREAMHANDLE_CONTEXT, sizeof(Sysmon_Flt_Stream_Context), 'xchf'); RegisterOptRegistration( 0, IRP_MJ_CREATE, 0, FLTPRE(SysmonFltPreOperation), FLTPOST(SysmonFltPostOperation) ); RegisterOptRegistration( 1, IRP_MJ_CLEANUP, 0, FLTPRE(SysmonFltPreOperation), FLTPOST(SysmonFltPostOperation) ); RegisterOptRegistration( 2, IRP_MJ_SET_INFORMATION, 0, FLTPRE(SysmonFltPreOperation), FLTPOST(SysmonFltPostOperation) ); RegisterOptRegistration( 3, IRP_MJ_CLOSE, 0, FLTPRE(SysmonFltPreOperation), FLTPOST(SysmonFltPostOperation) ); RegisterOptRegistration( 4, IRP_MJ_CREATE_NAMED_PIPE, 0, FLTPRE(SysmonFltPreOperation), FLTPOST(SysmonFltPostOperation) ); Status = FltRegisterFilter(DriverObj); return Status; } /**********************************************************************************/ #pragma LOCKEDCODE NTSTATUS CSysmonMiniFltFilter::FilterUnloadCallback( FLT_FILTER_UNLOAD_FLAGS Flags ) { return STATUS_SUCCESS; } /**********************************************************************************/ #pragma LOCKEDCODE NTSTATUS CSysmonMiniFltFilter::InstanceSetupCallback( PCFLT_RELATED_OBJECTS FltObjects, FLT_INSTANCE_SETUP_FLAGS Flags, DEVICE_TYPE VolumeDeviceType, FLT_FILESYSTEM_TYPE VolumeFilesystemType ) { if ( VolumeDeviceType == FILE_DEVICE_DISK_FILE_SYSTEM) { return STATUS_SUCCESS; } // if (VolumeFilesystemType != FLT_FSTYPE_NPFS) // { // } } /**********************************************************************************/ #pragma LOCKEDCODE NTSTATUS CSysmonMiniFltFilter::InstanceQueryTeardownCallback( PCFLT_RELATED_OBJECTS FltObjects, FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags ) { return STATUS_SUCCESS; } ================================================ FILE: Sysmon.sys/CSysmonMiniFltFilter.h ================================================ #ifndef _CSysmonMiniFltFilter_h #define _CSysmonMiniFltFilter_h #include #include #include #include class CSysmonMiniFltFilter : public CMiniFltFilter { public: CSysmonMiniFltFilter(void); ~CSysmonMiniFltFilter(void); CErrorStatus Init(PDRIVER_OBJECT DriverObj); public: static NTSTATUS NTAPI FilterUnloadCallback( FLT_FILTER_UNLOAD_FLAGS Flags ); static NTSTATUS NTAPI InstanceSetupCallback( PCFLT_RELATED_OBJECTS FltObjects, FLT_INSTANCE_SETUP_FLAGS Flags, DEVICE_TYPE VolumeDeviceType, FLT_FILESYSTEM_TYPE VolumeFilesystemType ); static NTSTATUS NTAPI InstanceQueryTeardownCallback( PCFLT_RELATED_OBJECTS FltObjects, FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags ); private: // CListEntry mListFile; }; #endif ================================================ FILE: Sysmon.sys/ReadMe.txt ================================================ ======================================================================== DYNAMIC LINK LIBRARY : Sysmon.sys Project Overview ======================================================================== AppWizard has created this Sysmon.sys DLL for you. This file contains a summary of what you will find in each of the files that make up your Sysmon.sys application. Sysmon.sys.vcxproj This is the main project file for VC++ projects generated using an Application Wizard. It contains information about the version of Visual C++ that generated the file, and information about the platforms, configurations, and project features selected with the Application Wizard. Sysmon.sys.vcxproj.filters This is the filters file for VC++ projects generated using an Application Wizard. It contains information about the association between the files in your project and the filters. This association is used in the IDE to show grouping of files with similar extensions under a specific node (for e.g. ".cpp" files are associated with the "Source Files" filter). Sysmon.sys.cpp This is the main DLL source file. When created, this DLL does not export any symbols. As a result, it will not produce a .lib file when it is built. If you wish this project to be a project dependency of some other project, you will either need to add code to export some symbols from the DLL so that an export library will be produced, or you can set the Ignore Input Library property to Yes on the General propert page of the Linker folder in the project's Property Pages dialog box. ///////////////////////////////////////////////////////////////////////////// Other standard files: StdAfx.h, StdAfx.cpp These files are used to build a precompiled header (PCH) file named Sysmon.sys.pch and a precompiled types file named StdAfx.obj. ///////////////////////////////////////////////////////////////////////////// Other notes: AppWizard uses "TODO:" comments to indicate parts of the source code you should add to or customize. ///////////////////////////////////////////////////////////////////////////// ================================================ FILE: Sysmon.sys/Sysmon.sys.cpp ================================================ // Sysmon.sys.cpp : Defines the exported functions for the DLL application. // #include "stdafx.h" #include /**********************************************************************************/ #pragma INITCODE #ifdef __cplusplus extern "C" #endif NTSTATUS NTAPI DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { return 0; } ================================================ FILE: Sysmon.sys/Sysmon.sys.vcxproj ================================================  Debug Win32 Debug x64 Release Win32 Release x64 {E179CA60-36AC-4DCC-8B87-06214F32DD0B} Win32Proj Sysmonsys DynamicLibrary true Unicode DynamicLibrary true Unicode DynamicLibrary false true Unicode DynamicLibrary false true Unicode false true false false false false Sysmon64 .sys NotUsing Level3 Disabled WIN32;_X86_ $(WDK_PATH_INCLUDE);cpplib\;%(AdditionalIncludeDirectories) Disabled false false false Default MultiThreadedDebug false false false false ProgramDatabase StdCall Native true $(WDK_PATH_LIB);FltMgr.lib true CDriverEntry::Init 0x10000 $(WDK_PATH_LIB_DIR) $(OutDir)$(TargetName) /INTEGRITYCHECK %(AdditionalOptions) NotUsing Level3 Disabled WIN64;_WIN64;_AMD64_ $(WDK_PATH_INCLUDE);cpplib\;%(AdditionalIncludeDirectories) Disabled false false false Default MultiThreadedDebug false false false false ProgramDatabase StdCall Native true $(WDK_PATH_LIB_64) true CDriverEntry::Init 0x10000 $(OutDir)$(TargetName) /INTEGRITYCHECK %(AdditionalOptions) Level3 NotUsing Disabled false false WIN32;_X86_ $(WDK_PATH_INCLUDE);cpplib\;%(AdditionalIncludeDirectories) Disabled false false MultiThreaded false StdCall None Default Native true true true CDriverEntry::Init 0x10000 $(OutDir)$(TargetName) $(WDK_PATH_LIB);FltMgr.lib true /INTEGRITYCHECK %(AdditionalOptions) $(WDK_PATH_LIB_DIR) Level3 NotUsing Disabled false false WIN64;_WIN64;_AMD64_ $(WDK_PATH_INCLUDE);cpplib\;%(AdditionalIncludeDirectories) Disabled false false MultiThreaded false StdCall Native true true true CDriverEntry::Init 0x10000000 $(OutDir)$(TargetName)$(TargetExt) $(WDK_PATH_LIB_64) true /INTEGRITYCHECK %(AdditionalOptions) Create Create Create Create ================================================ FILE: Sysmon.sys/Sysmon.sys.vcxproj.filters ================================================  {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms {c03ff512-8920-4e38-b76a-ef373713f0ca} Header Files Header Files cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib Header Files Header Files Header Files cpplib cpplib Header Files cpplib cpplib Header Files Header Files cpplib Header Files Source Files Source Files cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib cpplib Source Files Source Files Source Files cpplib cpplib Source Files cpplib cpplib Source Files Source Files cpplib ================================================ FILE: Sysmon.sys/Sysmon.sys.vcxproj.user ================================================  ================================================ FILE: Sysmon.sys/cpplib/CAssert.h ================================================ #ifndef _CAssert_h #define _CAssert_h #define CAssert( a ) #define CAssertAddrValid( a , b) #endif ================================================ FILE: Sysmon.sys/cpplib/CAttachDevice.cpp ================================================ #include "CAttachDevice.h" #include "CDebug.h" /**********************************************************************************/ #pragma PAGEDCODE CAttachDevice::CAttachDevice(void) :mDeviceObject(NULL), mLowDeviceObject(NULL) { RtlInitUnicodeString( &mDriverPath, L"\\Device\\xxx" ); } /**********************************************************************************/ #pragma LOCKEDCODE CAttachDevice::~CAttachDevice(void) { } /**********************************************************************************/ #pragma INITCODE CErrorStatus CAttachDevice::Init( PDEVICE_OBJECT AttachDevice, PDEVICE_OBJECT OldDevice ) { CErrorStatus Error; Error = STATUS_SUCCESS; mDeviceObject = AttachDevice; mLowDeviceObject = OldDevice; return Error; } /**********************************************************************************/ #pragma LOCKEDCODE CErrorStatus CAttachDevice::Attach( PDRIVER_OBJECT Driver, UNICODE_STRING& DeviceName) { CErrorStatus Error; PDEVICE_OBJECT AttachDeviceObject; PDEVICE_OBJECT OldDeviceObject; Error = IoCreateDevice( Driver, 0, NULL, FILE_DEVICE_UNKNOWN, 0, TRUE, &AttachDeviceObject); if ( Error.IsNtSuccess()) { //AttachDeviceObject->Flags |= DO_DIRECT_IO; Error = IoAttachDevice( AttachDeviceObject, &DeviceName, &OldDeviceObject); if (Error.IsNtSuccess()) { CDebug::DebugOut( "CAfdAttachDevice: IoAttachDevice(%S): 0x%x\n", DeviceName.Buffer, Error); Init( AttachDeviceObject, OldDeviceObject); } //KdPrint(("[tdi_fw] DriverEntry: %S fileobj: 0x%x\n", devname, *fltobj)); //return status; } else { CDebug::DebugOut( "CAfdAttachDevice: IoCreateDevice(%S): 0x%x\n", DeviceName.Buffer, Error); } return Error; } ================================================ FILE: Sysmon.sys/cpplib/CAttachDevice.h ================================================ #ifndef _CAfdAttachDevice_H #define _CAfdAttachDevice_H #include "cpplib.h" #include "CListEntry.h" #include "CErrorStatus.h" class CAttachDevice { public: CAttachDevice(void); virtual ~CAttachDevice(void); void operator =( PDEVICE_OBJECT DeviceObject) { mDeviceObject = DeviceObject; } PDEVICE_OBJECT Device() { return mDeviceObject; } PDEVICE_OBJECT LowDevice() { return mLowDeviceObject; } CErrorStatus Init( PDEVICE_OBJECT AttachDevice, PDEVICE_OBJECT OldDevice ); CErrorStatus Attach( PDRIVER_OBJECT Driver, UNICODE_STRING& DeviceName); private: PDEVICE_OBJECT mDeviceObject; PDEVICE_OBJECT mLowDeviceObject; UNICODE_STRING mDriverPath; }; #endif ================================================ FILE: Sysmon.sys/cpplib/CDebug.cpp ================================================ #include "cpplib.h" #include "CDebug.h" #include #include CDebug::CDebug(void) { } CDebug::~CDebug(void) { } #ifdef DEBUG void CDebug::DebugOut( const CHAR* formatStr, ... ) { CHAR StrBuf[kMaxLengthString]; va_list ArgList; memset( StrBuf , 0 , kMaxLengthString ); va_start(ArgList, formatStr); _vsnprintf( StrBuf, kMaxLengthString, formatStr, ArgList); va_end(ArgList); KdPrint(("[AfdFilter]:")); KdPrint((StrBuf)); KdPrint(("\n")); } #endif ================================================ FILE: Sysmon.sys/cpplib/CDebug.h ================================================ #ifndef _CDebug_h #define _CDebug_h #include "cpplib.h" class CDebug { public: typedef enum {kMaxLengthString = 256}; CDebug(void); ~CDebug(void); #ifdef DEBUG static void DebugOut( const CHAR* formatStr, ... ); #else static inline void DebugOut( const CHAR* formatStr, ... ) { } #endif }; #endif ================================================ FILE: Sysmon.sys/cpplib/CDeviceObject.cpp ================================================ #include "CDeviceObject.h" #include "CAssert.h" #include "CDebug.h" CDeviceObject::CDeviceObject(void) :mDeviceObject(NULL) { } CDeviceObject::CDeviceObject(PDEVICE_OBJECT Device) { mDeviceObject = Device; } CDeviceObject::CDeviceObject(const CDeviceObject& Device) { mDeviceObject = Device.mDeviceObject; } CDeviceObject::~CDeviceObject(void) { mDeviceObject = NULL; } CDeviceObject::operator const PDEVICE_OBJECT() const { return mDeviceObject; } CDeviceObject::operator PDEVICE_OBJECT &() { return mDeviceObject; } PDEVICE_OBJECT* CDeviceObject::operator &() { return &mDeviceObject; } void CDeviceObject::operator =(PDEVICE_OBJECT Device) { mDeviceObject = Device; } bool CDeviceObject::operator !=(PDEVICE_OBJECT DeviceObject) { return (mDeviceObject != DeviceObject); } bool CDeviceObject::operator !() { return (mDeviceObject == NULL); } ULONG& CDeviceObject::Flags() { return mDeviceObject->Flags; } PVOID& CDeviceObject::DeviceExtension() { return mDeviceObject->DeviceExtension; } PDRIVER_OBJECT& CDeviceObject::DriverObject() { return mDeviceObject->DriverObject; } ULONG& CDeviceObject::DeviceType() { return mDeviceObject->DeviceType; } PDEVICE_OBJECT& CDeviceObject::AttachedDevice() { return mDeviceObject->AttachedDevice; } PDEVICE_OBJECT& CDeviceObject::NextDevice() { return mDeviceObject->NextDevice; } ULONG& CDeviceObject::Characteristics() { return mDeviceObject->Characteristics; } /**********************************************************************************/ #pragma LOCKEDCODE CErrorStatus CDeviceObject::Init( PDRIVER_OBJECT Driver, CStackStringW<256>& DeviceName, CStackStringW<256>& DosDeviceName, const UINT32 DeviceExtSize ) { CErrorStatus Error; UINT32 Index; CUnicodeString IoDeviceName; Index = 0; IoDeviceName = &DeviceName; Error = Create( Driver, DeviceExtSize, IoDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE ); if (Error.IsNtSuccess()) { Error = Link(&DosDeviceName,IoDeviceName); if ( !Error.IsNtSuccess() ) { Delete(); } else { Flags() &= 0xFFFFFF7F; } } return Error; } /**********************************************************************************/ #pragma LOCKEDCODE CErrorStatus CDeviceObject::Create( PDRIVER_OBJECT DriverObject, const UINT32 DeviceExtSize, CUnicodeString& DeviceName, DEVICE_TYPE DeviceType, UINT32 DeviceChars, BOOL Exclusive ) { CErrorStatus Error; CAssert(!IsAttached()); Error = ::IoCreateDevice( DriverObject, DeviceExtSize, (PUNICODE_STRING)DeviceName, DeviceType, DeviceChars, Exclusive, &mDeviceObject); if ( Error.IsNtSuccess()) { // CDebug::DebugOut( // "CDeviceObject::IoCreateDevice(%S): 0x%x\n", // DeviceName.Buffer, // Error); } return Error; } /**********************************************************************************/ #pragma LOCKEDCODE CErrorStatus CDeviceObject::Link( const WCHAR* LinkName, CUnicodeString& DeviceName) const { CErrorStatus Error; CUnicodeString DeviceLinkName; CAssert(IsAttached()); CAssert(WeCreated()); CAssert(!WeLinked()); do { if (!LinkName) { Error = STATUS_INVALID_ADDRESS; break; } DeviceLinkName = LinkName; Error = IoCreateSymbolicLink( DeviceLinkName, DeviceName ); } while (FALSE); return Error; } /**********************************************************************************/ #pragma PAGEDCODE void CDeviceObject::Delete() { if (mDeviceObject) { ::IoDeleteDevice(mDeviceObject); } } /**********************************************************************************/ #pragma PAGEDCODE void CDeviceObject::DeleteSymbolicLink(CStackStringW<256>& SymbolicLink) { CUnicodeString SymbolicLinkName; SymbolicLinkName = SymbolicLink; ::IoDeleteSymbolicLink(SymbolicLinkName); } ================================================ FILE: Sysmon.sys/cpplib/CDeviceObject.h ================================================ #ifndef _CDeviceObject_h #define _CDeviceObject_h #include "cpplib.h" #include "CErrorStatus.h" #include "CString.h" #include "CUnicodeString.h" class CDeviceObject { public: CDeviceObject(void); CDeviceObject(PDEVICE_OBJECT Device); CDeviceObject(const CDeviceObject& Device); ~CDeviceObject(void); public: operator const PDEVICE_OBJECT() const; operator PDEVICE_OBJECT&(); PDEVICE_OBJECT* operator &(); void operator =(PDEVICE_OBJECT Device); bool operator !=(PDEVICE_OBJECT DeviceObject); bool operator !(); ULONG& Flags(); ULONG& Characteristics(); ULONG& DeviceType(); PVOID& DeviceExtension(); PDRIVER_OBJECT& DriverObject(); PDEVICE_OBJECT& AttachedDevice(); PDEVICE_OBJECT& NextDevice(); CErrorStatus ObQueryNameString(); CErrorStatus Init( PDRIVER_OBJECT Driver, CStackStringW<256>& DeviceName, CStackStringW<256>& DosDeviceName, const UINT32 DeviceExtSize ); CErrorStatus Create( PDRIVER_OBJECT DriverObject, const UINT32 DeviceExtSize, CUnicodeString& DeviceName, DEVICE_TYPE DeviceType, UINT32 DeviceChars, BOOL Exclusive ); CErrorStatus Link( const WCHAR* LinkName, CUnicodeString& DeviceName) const; void Delete(); void DeleteSymbolicLink(CStackStringW<256>& SymbolicLink); private: /* * ...豸... */ PDEVICE_OBJECT mDeviceObject; }; #endif ================================================ FILE: Sysmon.sys/cpplib/CDispatchEngine.cpp ================================================ #include "CDispatchEngine.h" CDispatchEngine::CDispatchEngine(void) { } CDispatchEngine::~CDispatchEngine(void) { } ================================================ FILE: Sysmon.sys/cpplib/CDispatchEngine.h ================================================ #ifndef _CDispatchEngine_h #define _CDispatchEngine_h class CDispatchEngine { public: CDispatchEngine(void); virtual ~CDispatchEngine(void); }; #endif ================================================ FILE: Sysmon.sys/cpplib/CDriverDispatch.cpp ================================================ #include "CDriverDispatch.h" CDriverDispatch::CDriverDispatch(void) :mDriverDisptach(NULL) { } CDriverDispatch::CDriverDispatch(const PDRIVER_DISPATCH* DriverDisptach) { mDriverDisptach = (PDRIVER_DISPATCH*)DriverDisptach; } CDriverDispatch::~CDriverDispatch(void) { } void CDriverDispatch::operator =(const PDRIVER_DISPATCH* DriverDisptach) { mDriverDisptach = (PDRIVER_DISPATCH*)DriverDisptach; } BOOL CDriverDispatch::operator !() const { return mDriverDisptach != NULL; } PDRIVER_DISPATCH& CDriverDispatch::operator [](int n) { return mDriverDisptach[n]; } ================================================ FILE: Sysmon.sys/cpplib/CDriverDispatch.h ================================================ #ifndef _CDriverDispatch_h #define _CDriverDispatch_h #include class CDriverDispatch { public: CDriverDispatch(void); CDriverDispatch(const PDRIVER_DISPATCH* DriverDisptach); virtual ~CDriverDispatch(void); void operator =(const PDRIVER_DISPATCH* DriverDisptach); BOOL operator !() const; PDRIVER_DISPATCH& operator [](int n); private: PDRIVER_DISPATCH* mDriverDisptach; }; #endif ================================================ FILE: Sysmon.sys/cpplib/CDriverObject.cpp ================================================ #include "CDriverObject.h" CDriverObject::CDriverObject(void) { } CDriverObject::CDriverObject(PDRIVER_OBJECT DriverObject) { mDriverObject = DriverObject; } CDriverObject::CDriverObject(const CDriverObject& DriverObject) { mDriverObject = DriverObject.mDriverObject; } CDriverObject::~CDriverObject(void) { } CDriverObject::operator const PDRIVER_OBJECT() const { return mDriverObject; } ================================================ FILE: Sysmon.sys/cpplib/CDriverObject.h ================================================ #ifndef _CDriverObject_h #define _CDriverObject_h #include "cpplib.h" class CDriverObject { public: CDriverObject(void); CDriverObject(PDRIVER_OBJECT DriverObject); CDriverObject(const CDriverObject& DriverObject); ~CDriverObject(void); public: operator const PDRIVER_OBJECT() const; private: PDRIVER_OBJECT mDriverObject; }; #endif ================================================ FILE: Sysmon.sys/cpplib/CEResource.cpp ================================================ #include "CEResource.h" CEResource::CEResource(void) { //mReference = 0; ExInitializeResource(&mEResoure); } CEResource::~CEResource(void) { ExDeleteResource(&mEResoure); } void CEResource::Lock() { ExAcquireResourceExclusive(&mEResoure,true); } void CEResource::UnLock() { ExReleaseResource(&mEResoure); } ================================================ FILE: Sysmon.sys/cpplib/CEResource.h ================================================ #ifndef _CEResource_h #define _CEResource_h #include "cpplib.h" class CEResource { public: CEResource(void); ~CEResource(void); void Lock(); void UnLock(); private: ERESOURCE mEResoure; //volatile LONG mReference; }; #endif ================================================ FILE: Sysmon.sys/cpplib/CErrorStatus.cpp ================================================ #include "CErrorStatus.h" CErrorStatus::CErrorStatus(void) { mNtStatus = STATUS_UNSUCCESSFUL; } CErrorStatus::~CErrorStatus(void) { } CErrorStatus::CErrorStatus( NTSTATUS Status ) { mNtStatus = Status; } CErrorStatus::CErrorStatus(const CErrorStatus& Error ) { mNtStatus = Error.mNtStatus; mSystemError = Error.mSystemError; } void CErrorStatus::operator =( NTSTATUS Status ) { mNtStatus = Status; } BOOL CErrorStatus::IsNtSuccess() { return NT_SUCCESS(mNtStatus); } ================================================ FILE: Sysmon.sys/cpplib/CErrorStatus.h ================================================ #ifndef _CErrorStatus_H #define _CErrorStatus_H #include "cpplib.h" class CErrorStatus { public: CErrorStatus(void); ~CErrorStatus(void); CErrorStatus( NTSTATUS Status ); CErrorStatus(const CErrorStatus& Error ); void operator =( NTSTATUS Status ); operator NTSTATUS() { return mNtStatus; } BOOL IsNtSuccess(); private: NTSTATUS mNtStatus; ULONG mSystemError; }; #endif ================================================ FILE: Sysmon.sys/cpplib/CFileObject.cpp ================================================ #include "cpplib.h" #include "CFileObject.h" CFileObject::CFileObject(void) :mFileObj(NULL) { } CFileObject::CFileObject(const CFileObject& File) { mFileObj = mFileObj; } CFileObject::CFileObject(const PFILE_OBJECT& File) { mFileObj = File; } CFileObject::~CFileObject(void) { } CFileObject::operator PFILE_OBJECT() { return mFileObj; } PVOID CFileObject::operator !() { return (PVOID)!mFileObj; } PUNICODE_STRING CFileObject::FileName() { return &mFileObj->FileName; } PFILE_OBJECT& CFileObject::RelatedFileObject() { return mFileObj->RelatedFileObject; } ================================================ FILE: Sysmon.sys/cpplib/CFileObject.h ================================================ #ifndef _CFileObject_h #define _CFileObject_h class CFileObject { public: CFileObject(void); CFileObject(const CFileObject& File); CFileObject(const PFILE_OBJECT& File); ~CFileObject(void); operator PFILE_OBJECT(); PVOID operator !(); PUNICODE_STRING FileName(); PFILE_OBJECT& RelatedFileObject(); private: PFILE_OBJECT mFileObj; }; #endif ================================================ FILE: Sysmon.sys/cpplib/CFilterDevice.cpp ================================================ #include "CFilterDevice.h" #include "CIrp.h" #include "CppLib.h" #include "CAssert.h" WCHAR* CFilterDevice::sDeviceName = L"\\Device\\XXXXXXX"; WCHAR* CFilterDevice::sLinkName = L"\\DosDevices\\XXXXXXX"; CFilterDevice::CFilterDevice(void) :mDeviceObject(NULL), mDriverObject(NULL), mIsAttached(FALSE), mWeCreated(FALSE), mWeLinked(NULL), mFileObjectToUse(NULL), mDispatchFunc(NULL), mRefPtr(NULL), mIsRelease(FALSE) { } CFilterDevice::~CFilterDevice(void) { } CErrorStatus CFilterDevice::Init( PDRIVER_OBJECT Driver, PUNICODE_STRING Registry, const UINT32 DeviceExtSize) { CErrorStatus Error; UINT32 Index; Index = 0; Error = Create( Driver, DeviceExtSize, sDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, NULL, NULL ); if (Error.IsNtSuccess()) { // for ( Index = 0; Index < IRP_MJ_MAXIMUM_FUNCTION ; Index++) // { // Driver->MajorFunction[Index] = CAfdFilterDispatch::FilterDispatch; // } //Error = AfdFastIo.Init(Driver); //if (Error.IsNtSuccess()) //{ //Error = CZPMountEngine::Init(this); //if ( Error.IsNtSuccess()) //{ Error = Link(sLinkName); if ( !Error.IsNtSuccess() ) { Delete(); } else { // Error = ToAttachDevice( L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Afd" ); // // if ( !Error.IsNtSuccess()) // { // Unlink(); // Delete(); // } } //} //} mIsRelease = TRUE; } return Error; } CErrorStatus CFilterDevice::Create( PDRIVER_OBJECT DriverObject, const UINT32 DeviceExtSize, const WCHAR* DeviceName, DEVICE_TYPE DeviceType, UINT32 DeviceChars, BOOL Exclusive, IrpDispatchFunc DispatchFunc, void *RefPtr) { CErrorStatus Error; CAssert(!IsAttached()); CAssertAddrValid( DispatchFunc, IrpDispatchFunc); RtlInitUnicodeString( &mDeviceName , DeviceName ); Error = IoCreateDevice( DriverObject, DeviceExtSize, &mDeviceName, DeviceType, DeviceChars, Exclusive, &mDeviceObject); if ( Error.IsNtSuccess()) { mDriverObject = DriverObject; mDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; mDeviceObject->Flags |= DO_DIRECT_IO; mDeviceObject->DeviceExtension = this; mIsAttached = TRUE; mWeCreated = TRUE; mDispatchFunc = DispatchFunc; mRefPtr = RefPtr; } return Error; } void CFilterDevice::Delete() { CAssert(IsAttached()); CAssert(WeCreated()); CAssert(!WeLinked()); IoDeleteDevice(mDeviceObject); //mDeviceName.Empty(); mIsAttached = FALSE; mDeviceObject = NULL; mDispatchFunc = NULL; mRefPtr = NULL; } CErrorStatus CFilterDevice::Link(const WCHAR* LinkName) { CErrorStatus Error; CAssert(IsAttached()); CAssert(WeCreated()); CAssert(!WeLinked()); RtlInitUnicodeString( &mDeviceLinkName, LinkName ); //if ( Error.IsNtSuccess() ) //{ Error = IoCreateSymbolicLink( &mDeviceLinkName, &mDeviceName ); //} if ( Error.IsNtSuccess()) { mWeLinked = TRUE; } return Error; } CErrorStatus CFilterDevice::Unlink() { CErrorStatus Error; CAssert(IsAttached()); CAssert(WeCreated()); CAssert(WeLinked()); Error = IoDeleteSymbolicLink( &mDeviceLinkName ); if ( Error.IsNtSuccess() ) { mWeLinked = FALSE; } return Error; } CErrorStatus CFilterDevice::ToAttachDevice( WCHAR* DeviceName ) { CErrorStatus Error; UNICODE_STRING AttachDeviceName; PDEVICE_OBJECT DeviceObject; FILE_OBJECT* FileObject; RtlInitUnicodeString( &AttachDeviceName , DeviceName); Error = ZwLoadDriver(&AttachDeviceName); if ( Error.IsNtSuccess() || Error == STATUS_IMAGE_ALREADY_LOADED ) { RtlInitUnicodeString(&AttachDeviceName, L"\\Device\\Afd"); Error = IoGetDeviceObjectPointer( &AttachDeviceName, FILE_READ_ATTRIBUTES, &FileObject, &DeviceObject); if ( Error.IsNtSuccess() ) { Error = mAttachDevice.Attach( mDriverObject,AttachDeviceName); if ( Error.IsNtSuccess() ) { mIsAttached = TRUE; } } } return Error; } PDEVICE_OBJECT CFilterDevice::Device() { return mDeviceObject; } CAttachDevice& CFilterDevice::AttachDevice() { CAttachDevice AttachDev; return AttachDev; } ================================================ FILE: Sysmon.sys/cpplib/CFilterDevice.h ================================================ #ifndef _CFilterDevice_H #define _CFilterDevice_H #include "cpplib.h" #include "CErrorStatus.h" #include "CAttachDevice.h" class CFilterDevice; class CIrp; typedef CErrorStatus ( NTAPI *IrpDispatchFunc)( CFilterDevice * FilterDevice, CIrp&Irp, void* RefPtr, BOOL& IsIrpCompleted); class CFilterDevice { public: CFilterDevice(void); ~CFilterDevice(void); public: CErrorStatus Create( PDRIVER_OBJECT Driver ); CErrorStatus Init( PDRIVER_OBJECT Driver, PUNICODE_STRING Registry, const UINT32 DeviceExtSize ); CErrorStatus Create( PDRIVER_OBJECT DriverObject, const UINT32 DeviceExtSize, const WCHAR* DeviceName, DEVICE_TYPE DeviceType, UINT32 DeviceChars, BOOL Exclusive, IrpDispatchFunc DispatchFunc, void *RefPtr); CErrorStatus Link( const WCHAR* LinkName); CErrorStatus Unlink(); void Delete(); PDEVICE_OBJECT Device(); static CAttachDevice& AttachDevice(); PDRIVER_OBJECT DriverObject() const {return mDriverObject;}; operator PDEVICE_OBJECT() {return mDeviceObject;}; operator const PDEVICE_OBJECT() const {return mDeviceObject;}; BOOL IsAttached() const{return mIsAttached;}; BOOL WeCreated() const {return mWeCreated;}; BOOL WeLinked() const {return mWeLinked;}; CErrorStatus ToAttachDevice( WCHAR* DeviceName ); CErrorStatus DispatchIrp( CIrp& Irp, BOOL& IsIrpCompleted ); private: /* * ...豸... */ DEVICE_OBJECT* mDeviceObject; /* * ...... */ DRIVER_OBJECT* mDriverObject; /* Attach豸 */ CAttachDevice mAttachDevice; /* * ...豸(DeviceName)... */ UNICODE_STRING mDeviceName; /* * ...豸(LinkName)... */ UNICODE_STRING mDeviceLinkName; /* * ...豸... */ void* mRefPtr; /* * ...豸Ƿ񱻸Attached... */ BOOL mIsAttached; /* * ...豸Ƿ񱻴Created... */ BOOL mWeCreated; /* * ...豸ǷLinked... */ BOOL mWeLinked; /* * */ BOOL mIsRelease; /* * ...豸豸... */ PFILE_OBJECT mFileObjectToUse; IrpDispatchFunc mDispatchFunc; static WCHAR* sDeviceName; static WCHAR* sLinkName; }; #endif ================================================ FILE: Sysmon.sys/cpplib/CIntNumber.cpp ================================================ #include "CIntNumber.h" ================================================ FILE: Sysmon.sys/cpplib/CIntNumber.h ================================================ #ifndef _CIntNumber_h #define _CIntNumber_h #include "cpplib.h" template class CIntNumber { public: CIntNumber(void) { mNumber = 0; } CIntNumber(T _X ) { mNumber = _X; } CIntNumber(CIntNumber& _X ) { mNumber = (T)_X; } ~CIntNumber(void) { mNumber = 0; } operator T() const { return mNumber; } void operator ++() { mNumber++; } void operator =(T& _X) { mNumber = _X; } void operator =(CIntNumber& _X) { mNumber = (T)_X; } BOOL operator ==(T& _X) { return (mNumber == _X); } BOOL operator ==(CIntNumber& _X) { return (mNumber == (T)_X); } BOOL operator <(T& _X) { return (BOOL)(mNumber < _X); } BOOL operator <=(T& _X) { return (mNumber <= _X); } BOOL operator >(T& _X) { return (mNumber > _X); } BOOL operator >=(T& _X) { return (mNumber >= _X); } T mNumber; }; #endif ================================================ FILE: Sysmon.sys/cpplib/CIoStackLocation.cpp ================================================ #include "cpplib.h" #include "CIoStackLocation.h" CIoStackLocation::CIoStackLocation(void) :mStack(NULL) { } CIoStackLocation::CIoStackLocation( const CIoStackLocation& Stack) { mStack = Stack.mStack; } CIoStackLocation::CIoStackLocation(const PIO_STACK_LOCATION& Stack) { mStack = Stack; } CIoStackLocation::~CIoStackLocation(void) { } CIoStackLocation::operator PIO_STACK_LOCATION() { return mStack; } void CIoStackLocation::operator =(const PIO_STACK_LOCATION Stack) { mStack =Stack; } BOOLEAN CIoStackLocation::operator ==(const PIO_STACK_LOCATION Stack) { return ( mStack == Stack?true:false); } BOOLEAN CIoStackLocation::operator !=(const PIO_STACK_LOCATION Stack) { return (mStack != Stack?true:false); } PVOID CIoStackLocation::operator !() { return ((PVOID)!mStack); } CFileObject CIoStackLocation::FileObject() { return mStack->FileObject; } UCHAR& CIoStackLocation::Flags() { return mStack->Flags; } ================================================ FILE: Sysmon.sys/cpplib/CIoStackLocation.h ================================================ #ifndef _CIoStackLocation_h #define _CIoStackLocation_h #include "CFileObject.h" class CIoStackLocation { public: CIoStackLocation(void); CIoStackLocation(const CIoStackLocation& Stack); CIoStackLocation(const PIO_STACK_LOCATION& Stack); ~CIoStackLocation(void); operator PIO_STACK_LOCATION(); void operator =(const PIO_STACK_LOCATION Stack); BOOLEAN operator ==(const PIO_STACK_LOCATION Stack); BOOLEAN operator !=(const PIO_STACK_LOCATION Stack); PVOID operator !(); CFileObject FileObject(); UCHAR& Flags(); private: PIO_STACK_LOCATION mStack; }; #endif ================================================ FILE: Sysmon.sys/cpplib/CIrp.cpp ================================================ #include "cpplib.h" #include "CIrp.h" #include "CAssert.h" CIrp::CIrp(void) :mIrp(NULL) { } CIrp::CIrp(PIRP pIrp) :mIrp(NULL) { mIrp = pIrp; } CIrp::~CIrp() { mIrp = NULL; } PIRP CIrp::Get() const { return mIrp; } NTSTATUS& CIrp::Status() const { return mIrp->IoStatus.Status; } KPROCESSOR_MODE& CIrp::RequestorMode() const { return mIrp->RequestorMode; } ULONG_PTR& CIrp::Information() const { return mIrp->IoStatus.Information; } PMDL& CIrp::MdlAddress() const { return mIrp->MdlAddress; } PVOID& CIrp::UserBuffer() const { return mIrp->UserBuffer; } PVOID& CIrp::DriverContext1() const { return mIrp->Tail.Overlay.DriverContext[1]; } PVOID& CIrp::DriverContext2() const { return mIrp->Tail.Overlay.DriverContext[2]; } PVOID& CIrp::DriverContext3() const { return mIrp->Tail.Overlay.DriverContext[3]; } PVOID& CIrp::DriverContext4() const { return mIrp->Tail.Overlay.DriverContext[4]; } UINT8& CIrp::MajorFunction() const { return StackLocation()->MajorFunction; } UINT8& CIrp::MinorFunction() const { return StackLocation()->MinorFunction; } UINT8& CIrp::Flags() const { return StackLocation()->Flags; } UINT8& CIrp::Control() const { return StackLocation()->Control; } ULONG& CIrp::ReadLength() const { return StackLocation()->Parameters.Read.Length; } INT64& CIrp::ReadPos() const { return StackLocation()->Parameters.Read.ByteOffset.QuadPart; } ULONG& CIrp::WriteLength() const { return StackLocation()->Parameters.Write.Length; } INT64& CIrp::WritePos() const { return StackLocation()->Parameters.Write.ByteOffset.QuadPart; } ULONG& CIrp::IoctlCode() const { return StackLocation()->Parameters.DeviceIoControl.IoControlCode; } void *& CIrp::IoctlOutputBuffer() const { return mIrp->UserBuffer; } ULONG& CIrp::IoctlOutputBufferLength() const { return StackLocation()->Parameters.DeviceIoControl. OutputBufferLength; } void *& CIrp::IoctlInputBuffer() const { return mIrp->AssociatedIrp.SystemBuffer; } ULONG& CIrp::IoctlInputBufferLength() const { return StackLocation()->Parameters.DeviceIoControl.InputBufferLength; } void *& CIrp::IoctlType3InputBuffer() const { return StackLocation()->Parameters.DeviceIoControl.Type3InputBuffer; } PDEVICE_OBJECT& CIrp::Device() const { return StackLocation()->DeviceObject; } PFILE_OBJECT& CIrp::FileObject() const { return StackLocation()->FileObject; } PIO_STACK_LOCATION CIrp::StackLocation() const { if (mStackLocation == Current) return IoGetCurrentIrpStackLocation(mIrp); else return IoGetNextIrpStackLocation(mIrp); } void CIrp::UseCurrentStackLocation() { mStackLocation = Current; } void CIrp::UseNextStackLocation() { mStackLocation = Next; } void CIrp::CopyStackLocationToNext() const { IoCopyCurrentIrpStackLocationToNext(mIrp); } void CIrp::SkipStackLocation() const { IoSkipCurrentIrpStackLocation(mIrp); } NTSTATUS CIrp::Complete(NTSTATUS status, CCHAR boost) { Status() = status; IoCompleteRequest(mIrp, boost); return status; } NTSTATUS SimpleCompletion( DEVICE_OBJECT *device, IRP *irp, void* context) { ASSERT(irp); UNREFERENCED_PARAMETER(device); if(irp->PendingReturned) { ASSERT(context); KeSetEvent((KEVENT*) context, 0, false); } return STATUS_MORE_PROCESSING_REQUIRED; } NTSTATUS CIrp::SimpleSend(DEVICE_OBJECT *device) { KEVENT Event; NTSTATUS Status; KeInitializeEvent(&Event, NotificationEvent, false); IoSetCompletionRoutine( mIrp, SimpleCompletion, &Event, true, true, true); Status = IoCallDriver(device, mIrp); if(STATUS_PENDING == Status) { KeWaitForSingleObject(&Event, Executive, KernelMode, false, 0); Status = mIrp->IoStatus.Status; } return Status; } void CIrp::SetCancelRoutine(PDRIVER_CANCEL cancelFunc) { IoSetCancelRoutine(mIrp, cancelFunc); } void CIrp::MarkPending() { IoMarkIrpPending(mIrp); } void CIrp::UnmarkPending() { IoGetCurrentIrpStackLocation(mIrp)->Control &= ~SL_PENDING_RETURNED; } CErrorStatus CIrp::BuildDeviceIoControlRequest( UINT32 IoctlCode, PDEVICE_OBJECT Device, const void* InBuf, UINT32 SizeInBuf, void* OutBuf, UINT32 SizeOutBuf, BOOL Internal, KEVENT& Event, IO_STATUS_BLOCK& IoStatus) { CErrorStatus Error; CAssertAddrValid(pDeviceObject, DEVICE_OBJECT); mIrp = IoBuildDeviceIoControlRequest( IoctlCode, Device, const_cast(InBuf), SizeInBuf, OutBuf, SizeOutBuf, Internal, &Event, &IoStatus); if ( IsNull(mIrp) ) { Error = IoStatus.Status; } return Error; } CErrorStatus CIrp::BuildSynchronousFsdRequest( UINT32 majorFunc, PDEVICE_OBJECT pDeviceObject, const void *buf, UINT32 nBytes, INT64 pos, KEVENT& event, IO_STATUS_BLOCK& IoStatus) { CErrorStatus Error; CAssertAddrValid(pDeviceObject, DEVICE_OBJECT); LARGE_INTEGER liPos; liPos.QuadPart = pos; mIrp = IoBuildSynchronousFsdRequest(majorFunc, pDeviceObject, const_cast(buf), nBytes, &liPos, &event, &IoStatus); if (IsNull(mIrp)) { Error = IoStatus.Status; } return Error; } ================================================ FILE: Sysmon.sys/cpplib/CIrp.h ================================================ #ifndef _CIrp_h #define _CIrp_h #include "cpplib.h" #include "CErrorStatus.h" class CIrp { public: enum IrpStackLocation {Current, Next}; CIrp(void); CIrp(PIRP pIrp); ~CIrp(); operator PIRP (){ return mIrp;}; operator IRP&() {return *mIrp;}; operator const IRP&() const {return *mIrp;}; operator const PIRP() const {return mIrp;}; operator ULONG_PTR(){ return (ULONG_PTR)mIrp; }; PIRP operator->() {return mIrp;}; const PIRP operator->() const {return mIrp;}; PIRP Get() const; NTSTATUS& Status() const; KPROCESSOR_MODE& RequestorMode() const; ULONG_PTR& Information() const; PMDL& MdlAddress() const; PVOID& UserBuffer() const; PVOID& DriverContext1() const; PVOID& DriverContext2() const; PVOID& DriverContext3() const; PVOID& DriverContext4() const; UINT8& MajorFunction() const; UINT8& MinorFunction() const; UINT8& Flags() const; UINT8& Control() const; ULONG& ReadLength() const; INT64& ReadPos() const; ULONG& WriteLength() const; INT64& WritePos() const; ULONG& IoctlCode() const; void *& IoctlOutputBuffer() const; ULONG& IoctlOutputBufferLength() const; void *& IoctlInputBuffer() const; ULONG& IoctlInputBufferLength() const; void *& IoctlType3InputBuffer() const; PDEVICE_OBJECT& Device() const; PFILE_OBJECT& FileObject() const; PIO_STACK_LOCATION StackLocation() const; void UseCurrentStackLocation() ; void UseNextStackLocation(); void CopyStackLocationToNext() const; void SkipStackLocation() const; NTSTATUS Complete( NTSTATUS status, CCHAR boost = IO_NO_INCREMENT); void SetCancelRoutine(PDRIVER_CANCEL cancelFunc); void MarkPending(); void UnmarkPending(); CErrorStatus BuildDeviceIoControlRequest( UINT32 IoctlCode, PDEVICE_OBJECT Device, const void* InBuf, UINT32 SizeInBuf, void * OutBuf, UINT32 SizeOutBuf, BOOL Internal, KEVENT& event, IO_STATUS_BLOCK& IoStatus); CErrorStatus BuildSynchronousFsdRequest( UINT32 IoctlCode, PDEVICE_OBJECT Device, const void* InBuf, UINT32 nBytes, INT64 pos, KEVENT& event, IO_STATUS_BLOCK& IoStatus); NTSTATUS SimpleSend(DEVICE_OBJECT *device); private: IRP* mIrp; IrpStackLocation mStackLocation; }; #endif ================================================ FILE: Sysmon.sys/cpplib/CListEntry.cpp ================================================ #include "CListEntry.h" // template< typename T> // CAfdList::CAfdList() // { // InitializeListHead( &mAfdList); // } // // template< typename T> // CAfdList::~CAfdList() // { // // } // template< typename T> // void CAfdList::InsertHeadList() // { // // } ================================================ FILE: Sysmon.sys/cpplib/CListEntry.h ================================================ #ifndef _CListEntry_H #define _CListEntry_H #include "cpplib.h" #include "CEResource.h" #define LIST_COMMON_TAG 'Aflt' typedef struct _C_LIST_NODE { LIST_ENTRY Entry; void* Elment; }C_LIST_NODE; template< typename T, BOOLEAN IsHead = false, unsigned long PoolTag = LIST_COMMON_TAG > class CListEntry { public: class IteratorType { friend class CListEntry; public: IteratorType() { mPl = NULL; mPt = NULL; } IteratorType(const IteratorType& _T ) { mPt = _T.mPt; mPl = _T.mPl; } ~IteratorType() { } private: LIST_ENTRY* mPl; CListEntry* mPt; }; class Iterator { friend class CListEntry; friend class IteratorType; public: Iterator() { mT.mPl = NULL; mT.mPt = NULL; } Iterator( const Iterator& _I ) { mT.mPl = _I.mT.mPl; mT.mPt = _I.mT.mPt; } ~Iterator() { mT.mPl = NULL; if ( mT.mPt ) { mT.mPt->UnLock(); } } public: void operator++() { if ( mT.mPl ) { mT.mPl = mT.mPl->Flink; } } void operator--() { if ( mT.mPl ) { mT.mPl->Blink; } } T& operator *() { C_LIST_NODE* Node; Node = CONTAINING_RECORD( mT.mPl, C_LIST_NODE, Entry); return *((T*)Node->Elment); } BOOLEAN operator !=(Iterator& _I) { return (this != &_I); } BOOLEAN operator !=( LIST_ENTRY* _X ) { return (mT.mPl != _X); } void operator =( IteratorType& _X ) { mT.mPl = _X.mPl; mT.mPt = _X.mPt; } private: IteratorType mT; }; CListEntry() { InitializeListHead( &mAfdList); mIteratorType.mPl = mAfdList.Flink; mIteratorType.mPt = this; mMaxSize = -1; mSize = 0; } ~CListEntry() { } BOOLEAN push_front( T* _X ) { C_LIST_NODE* Entry; Entry = (C_LIST_NODE*) ExAllocatePoolWithTag( NonPagedPool, sizeof(C_LIST_NODE), PoolTag); if ( Entry ) { Lock(); __try { Entry->Elment = (void*)_X; InsertHeadList( &mAfdList, &Entry->Entry); } __finally { UnLock(); } return true; } return false; } BOOLEAN push_back( T* _X ) { C_LIST_NODE* Entry; Entry = (C_LIST_NODE*) ExAllocatePoolWithTag( NonPagedPool, sizeof(C_LIST_NODE), PoolTag); if ( Entry ) { Lock(); __try { Entry->Elment = (void*)_X; InsertTailList( &mAfdList, &Entry->Entry); } __finally { UnLock(); } return true; } return false; } BOOLEAN Insert( T* _X ) { if ( IsHead == true ) { return push_front( _X ); } else { return push_back(_X); } return false; } //ɾָĵ IteratorType& erase(Iterator& _I ) { IteratorType _T; C_LIST_NODE* Node; __try { _T.mPt = _I.mT.mPt; Node = CONTAINING_RECORD( _I.mT.mPl , C_LIST_NODE, Entry); if ( Node ) { RemoveEntryList(_I.mT.mPl); ExFreePool(Node); Node = NULL; } _T.mPl = _I.mT.mPl; } __except(EXCEPTION_EXECUTE_HANDLER) { } return _T; } BOOLEAN Remove( T* _X ) { LIST_ENTRY* Entry; C_LIST_NODE* Node; T* Elment; Lock(); __try { __try { Entry = &mAfdList; if( !IsListEmpty(Entry)) { while( Entry->Flink != &mAfdList ) { Node = CONTAINING_RECORD( Entry , C_LIST_NODE, Entry); if ( Node ) { if ( Node->Elment == _X ) { RemoveEntryList(Entry); ExFreePool(Node); Node = NULL; break; } } Entry = Entry->Flink; } } } __except(EXCEPTION_EXECUTE_HANDLER) { return false; } } __finally { UnLock(); } return true; } IteratorType& Begin() { Lock(); mIteratorType.mPl = mAfdList.Flink; mIteratorType.mPt = this; return mIteratorType; } LIST_ENTRY* End() { return &mAfdList; } private: void Lock() { mESourceLock.Lock(); } void UnLock() { mESourceLock.UnLock(); } IteratorType mIteratorType; LIST_ENTRY mAfdList; ULONG mMaxSize; ULONG mSize; CEResource mESourceLock; }; #endif ================================================ FILE: Sysmon.sys/cpplib/CMiniFltFilter.cpp ================================================ #include "CMiniFltFilter.h" #pragma comment(lib,"FltMgr.lib") /**********************************************************************************/ #pragma INITCODE CMiniFltFilter::CMiniFltFilter(void) :mFilter(NULL) { memset( &mFltRegistration, 0, sizeof(FLT_REGISTRATION)); mFltRegistration.Size = sizeof(FLT_REGISTRATION); mFltRegistration.Version = FLT_REGISTRATION_VERSION; mFltRegistration.Flags = 0; mFltRegistration.ContextRegistration = mContextRegistration; mFltRegistration.OperationRegistration = mOptRegistration; for ( int nI = 0; nI < MAX_FLT_OPERATION_REGISTRATION;nI++) { mOptRegistration[nI].MajorFunction = IRP_MJ_OPERATION_END; mOptRegistration[nI].Flags = 0; mOptRegistration[nI].PostOperation = 0; mOptRegistration[nI].PreOperation = 0; mOptRegistration[nI].Reserved1 = 0; } for ( int nI = 0; nI < MAX_FLT_CONTEXT_REGISTRATION; nI++) { mContextRegistration[nI].ContextType = FLT_CONTEXT_END; mContextRegistration[nI].ContextAllocateCallback = 0; mContextRegistration[nI].ContextCleanupCallback = 0; mContextRegistration[nI].ContextFreeCallback = 0; mContextRegistration[nI].Flags = 0; mContextRegistration[nI].PoolTag = 0; mContextRegistration[nI].Reserved1 = 0; mContextRegistration[nI].Size = 0; } mFilterUnloadCallback = 0; mInstanceSetupCallback = 0; mInstanceQueryTeardownCallback = 0; mInstanceTeardownStartCallback = 0; mInstanceTeardownCompleteCallback = 0; mGenerateFileNameCallback = 0; mNormalizeNameComponentCallback = 0; mNormalizeContextCleanupCallback = 0; mTransactionNotificationCallback = 0; mNormalizeNameComponentExCallback = 0; #if FLT_MGR_WIN8 mSectionNotificationCallback = 0; #endif // FLT_MGR_WIN8 } /**********************************************************************************/ #pragma LOCKEDCODE CMiniFltFilter::~CMiniFltFilter(void) { } /**********************************************************************************/ #pragma INITCODE void CMiniFltFilter::RegisterCallback(int nIndex,void* pFn) { if (nIndex == 0) { mFilterUnloadCallback = (PFLT_FILTER_UNLOAD_CALLBACK)pFn; mFltRegistration.FilterUnloadCallback = mFilterUnloadCallback; } if (nIndex == 1) { mInstanceSetupCallback = (PFLT_INSTANCE_SETUP_CALLBACK)pFn; mFltRegistration.InstanceSetupCallback = mInstanceSetupCallback; } if (nIndex == 2) { mInstanceQueryTeardownCallback = (PFLT_INSTANCE_QUERY_TEARDOWN_CALLBACK)pFn; mFltRegistration.InstanceQueryTeardownCallback = mInstanceQueryTeardownCallback; } if (nIndex == 3) { mInstanceTeardownStartCallback = (PFLT_INSTANCE_TEARDOWN_CALLBACK)pFn; mFltRegistration.InstanceTeardownStartCallback = mInstanceTeardownStartCallback; } if (nIndex == 4) { mInstanceTeardownCompleteCallback = (PFLT_INSTANCE_TEARDOWN_CALLBACK)pFn; mFltRegistration.InstanceTeardownCompleteCallback = mInstanceTeardownCompleteCallback; } if (nIndex == 5) { mGenerateFileNameCallback = (PFLT_GENERATE_FILE_NAME)pFn; mFltRegistration.GenerateFileNameCallback = mGenerateFileNameCallback; } if (nIndex == 6) { mNormalizeNameComponentCallback = (PFLT_NORMALIZE_NAME_COMPONENT)pFn; mFltRegistration.NormalizeNameComponentCallback = mNormalizeNameComponentCallback; } if (nIndex == 7) { mNormalizeContextCleanupCallback = (PFLT_NORMALIZE_CONTEXT_CLEANUP)pFn; mFltRegistration.NormalizeContextCleanupCallback = mNormalizeContextCleanupCallback; } if (nIndex == 8) { mTransactionNotificationCallback = (PFLT_TRANSACTION_NOTIFICATION_CALLBACK)pFn; mFltRegistration.TransactionNotificationCallback = mTransactionNotificationCallback; } if (nIndex == 9) { mNormalizeNameComponentExCallback = (PFLT_NORMALIZE_NAME_COMPONENT_EX)pFn; mFltRegistration.NormalizeNameComponentExCallback = mNormalizeNameComponentExCallback; } ; } /**********************************************************************************/ #pragma INITCODE void CMiniFltFilter::RegisterOptRegistration( int nIdex, USHORT MajorFunction, FLT_OPERATION_REGISTRATION_FLAGS Flags, PFLT_PRE_OPERATION_CALLBACK PreOperation, PFLT_POST_OPERATION_CALLBACK PostOperation, PVOID Reserved1 ) { mOptRegistration[nIdex].MajorFunction = static_cast(MajorFunction); mOptRegistration[nIdex].Flags = Flags; mOptRegistration[nIdex].PreOperation = PreOperation; mOptRegistration[nIdex].PostOperation = PostOperation; mOptRegistration[nIdex].Reserved1 = Reserved1; } void CMiniFltFilter::RegisterContext( int nIdex, FLT_CONTEXT_TYPE ContextType, USHORT ContextSize, ULONG PoolTag, PVOID Reserved1 ) { mContextRegistration[nIdex].Reserved1 = Reserved1; mContextRegistration[nIdex].Size = ContextSize; mContextRegistration[nIdex].ContextAllocateCallback = 0; mContextRegistration[nIdex].ContextCleanupCallback = 0; mContextRegistration[nIdex].ContextFreeCallback = 0; mContextRegistration[nIdex].ContextType = ContextType; mContextRegistration[nIdex].Size = ContextSize; mContextRegistration[nIdex].PoolTag = PoolTag; } /**********************************************************************************/ #pragma INITCODE CErrorStatus CMiniFltFilter::FltRegisterFilter(PDRIVER_OBJECT DriverObj) { CErrorStatus Status; Status = ::FltRegisterFilter(DriverObj,&mFltRegistration,&mFilter); if (Status.IsNtSuccess()) { ::FltStartFiltering(mFilter); } return Status; } /**********************************************************************************/ #pragma LOCKEDCODE NTSTATUS CMiniFltFilter::FilterUnloadCallback( FLT_FILTER_UNLOAD_FLAGS Flags ) { return STATUS_SUCCESS; } /**********************************************************************************/ #pragma LOCKEDCODE NTSTATUS CMiniFltFilter::InstanceSetupCallback( PCFLT_RELATED_OBJECTS FltObjects, FLT_INSTANCE_SETUP_FLAGS Flags, DEVICE_TYPE VolumeDeviceType, FLT_FILESYSTEM_TYPE VolumeFilesystemType ) { if ( VolumeDeviceType == FILE_DEVICE_DISK_FILE_SYSTEM) { return STATUS_SUCCESS; } // if (VolumeFilesystemType != FLT_FSTYPE_NPFS) // { // } return STATUS_UNSUCCESSFUL; } /**********************************************************************************/ #pragma LOCKEDCODE NTSTATUS CMiniFltFilter::InstanceQueryTeardownCallback( PCFLT_RELATED_OBJECTS FltObjects, FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags ) { return STATUS_SUCCESS; } ================================================ FILE: Sysmon.sys/cpplib/CMiniFltFilter.h ================================================ #ifndef _CMiniFltFilter_h #define _CMiniFltFilter_h #include #include "CErrorStatus.h" #define MAX_FLT_CONTEXT_REGISTRATION 20 #define MAX_FLT_OPERATION_REGISTRATION 50 typedef enum _Flt_Fn_Callback { kFilterUnloadCallback, kInstanceSetupCallbac, kInstanceQueryTeardowCallback, kInstanceTeardownStartCallback, kInstanceTeardownCompleteCallback, kGenerateFileNameCallback, kNormalizeNameComponentCallback, kNormalizeContextCleanupCallback, kTransactionNotificationCallback, kNormalizeNameComponentExCallback, }Flt_Fn_Callback; class CMiniFltFilter { public: CMiniFltFilter(void); virtual ~CMiniFltFilter(void); void RegisterCallback(int nIndex,void* pFn); void RegisterOptRegistration( int nIdex, USHORT ContextSize, FLT_OPERATION_REGISTRATION_FLAGS Flags, PFLT_PRE_OPERATION_CALLBACK PreOperation, PFLT_POST_OPERATION_CALLBACK PostOperation, PVOID Reserved1 = NULL ); void RegisterContext( int nIdex, FLT_CONTEXT_TYPE ContextType, USHORT ContextSize, ULONG PoolTag, PVOID Reserved1 = NULL ); CErrorStatus FltRegisterFilter(PDRIVER_OBJECT DriverObj); public: static NTSTATUS NTAPI FilterUnloadCallback( FLT_FILTER_UNLOAD_FLAGS Flags ); static NTSTATUS NTAPI InstanceSetupCallback( PCFLT_RELATED_OBJECTS FltObjects, FLT_INSTANCE_SETUP_FLAGS Flags, DEVICE_TYPE VolumeDeviceType, FLT_FILESYSTEM_TYPE VolumeFilesystemType ); static NTSTATUS NTAPI InstanceQueryTeardownCallback( PCFLT_RELATED_OBJECTS FltObjects, FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags ); private: PFLT_FILTER mFilter; FLT_REGISTRATION mFltRegistration; FLT_CONTEXT_REGISTRATION mContextRegistration[MAX_FLT_CONTEXT_REGISTRATION]; FLT_OPERATION_REGISTRATION mOptRegistration[MAX_FLT_OPERATION_REGISTRATION]; PFLT_FILTER_UNLOAD_CALLBACK mFilterUnloadCallback; PFLT_INSTANCE_SETUP_CALLBACK mInstanceSetupCallback; PFLT_INSTANCE_QUERY_TEARDOWN_CALLBACK mInstanceQueryTeardownCallback; PFLT_INSTANCE_TEARDOWN_CALLBACK mInstanceTeardownStartCallback; PFLT_INSTANCE_TEARDOWN_CALLBACK mInstanceTeardownCompleteCallback; PFLT_GENERATE_FILE_NAME mGenerateFileNameCallback; PFLT_NORMALIZE_NAME_COMPONENT mNormalizeNameComponentCallback; PFLT_NORMALIZE_CONTEXT_CLEANUP mNormalizeContextCleanupCallback; PFLT_TRANSACTION_NOTIFICATION_CALLBACK mTransactionNotificationCallback; PFLT_NORMALIZE_NAME_COMPONENT_EX mNormalizeNameComponentExCallback; #if FLT_MGR_WIN8 PFLT_SECTION_CONFLICT_NOTIFICATION_CALLBACK mSectionNotificationCallback; #endif // FLT_MGR_WIN8 }; #endif ================================================ FILE: Sysmon.sys/cpplib/CNPagedLookaside.cpp ================================================ #include "CNPagedLookaside.h" ================================================ FILE: Sysmon.sys/cpplib/CNPagedLookaside.h ================================================ #ifndef _CNPagedLookaside_h #define _CNPagedLookaside_h #include "cpplib.h" template< typename T, USHORT PoolTag = NPAGE_LIST_POOL_TAG> class CNPagedLookaside { public: CNPagedLookaside(void) { ExInitializeNPagedLookasideList( &mNPagedLookasside, 0, 0, 0, sizeof(T), PoolTag, 0); } ~CNPagedLookaside(void) { ExDeleteNPagedLookasideList(&mNPagedLookasside); } T* Allocate() { return static_cast(ExAllocateFromNPagedLookasideList(&mNPagedLookasside)); } void Free( T* pT ) { ExFreeToNPagedLookasideList(&mNPagedLookasside, pT); } private: NPAGED_LOOKASIDE_LIST mNPagedLookasside; }; #endif ================================================ FILE: Sysmon.sys/cpplib/CPool.cpp ================================================ #include "CPool.h" ================================================ FILE: Sysmon.sys/cpplib/CPool.h ================================================ #ifndef _CPool_h #define _CPool_h #include "cpplib.h" #include "CIntNumber.h" template class CPool { public: CPool(void) { mPool = NULL; mPoolSize = 0; mReference = 0; } CPool(const CPool& Pool ) { mPool = Pool.mPool; mPoolSize = Pool.mPoolSize; mReference = Pool.mReference; } ~CPool(void) { if ( mPool && AutoRelease == true ) { Free(); } } operator T*() const { return (T*)mPool; } BOOL operator ==( CIntNumber& Pointer ) { return (mPool == (T*)((INT3264)Pointer)); } BOOL operator !=( CIntNumber& Pointer ) { return (mPool != (T*) ((INT3264)Pointer)); } const T& operator []( INT3264 Index) const { if ( Index < Size() && Index >= 0 ) { return ((T*)*this)[Index]; } return ((T*)*this)[0]; } T& operator []( INT3264 Index ) { if ( Index >= Size() || Index < 0 ) { return ((T*)*this)[0]; } return ((T*)*this)[Index]; } // T& // operator=( T& _E ) // { // return _E; // } CPool& operator=( CPool& _X ) { mPool = (T*)_X; mPoolSize = _X.Size(); } T* Allocate( SIZE_T _S ) { if ( mPool == NULL ) { mPool = static_cast(ExAllocatePoolWithTag( PoolType, _S, PoolTag)); if ( mPool ) { mPoolSize = _S; } } return static_cast(mPool); } T* Allocate() { if ( mPool == NULL ) { mPool = static_cast(ExAllocatePoolWithTag( PoolType, sizeof(T), PoolTag)); if ( mPool ) { mPoolSize = sizeof(T); } } return mPool; } void Free() { if ( mPool ) { ExFreePool(mPool); mPool = NULL; mPoolSize = 0; } } INT3264 Size() { return mPoolSize; } private: T* mPool; ULONG_PTR mPoolSize; ULONG_PTR mReference; }; #endif ================================================ FILE: Sysmon.sys/cpplib/CString.cpp ================================================ #include "CString.h" ================================================ FILE: Sysmon.sys/cpplib/CString.h ================================================ #ifndef _CStringT_h #define _CStringT_h #include template class CStringT { public: CStringT(void) { } virtual ~CStringT(void) { } operator T*() { return pT; } protected: T pT[COUNT]; }; class CStringW: public CStringT { public: CStringW() { memset(this,0,sizeof(*this)); } ~CStringW() { } private: USHORT mLength; USHORT mMaxLength; }; template class CStackStringW : public CStringT { public: CStackStringW() { } ~CStackStringW() { } WCHAR& operator [](int n) { return pT[n]; } operator WCHAR*() { return &pT[0]; } WCHAR* operator &() { return &pT[0]; } }; #endif ================================================ FILE: Sysmon.sys/cpplib/CSysmonBase.cpp ================================================ #include "CSysmonBase.h" #include #include CSysmonBase::CSysmonBase(void) { } CSysmonBase::~CSysmonBase(void) { } /**********************************************************************************/ #pragma LOCKEDCODE USHORT CSysmonBase::SysmonIsNamedPipe(PCFLT_RELATED_OBJECTS pFltFileObj) { CErrorStatus Status; USHORT Type; UNICODE_STRING DestinationString; UNICODE_STRING String2; UNICODE_STRING String1; SIZE_T NumberOfBytes; String1.Buffer = 0; String1.Length = 0; Status = FltGetVolumeName( pFltFileObj->Volume, &String1, &NumberOfBytes); if ( Status == STATUS_BUFFER_TOO_SMALL ) { if ( NumberOfBytes != 36 && NumberOfBytes != 34 ) return 0; String1.Buffer = (PWSTR)ExAllocatePoolWithTag( NonPagedPool, NumberOfBytes, 'PsyS'); if ( !String1.Buffer ) return 0; String1.Length = NumberOfBytes & 0xFF; String1.MaximumLength = NumberOfBytes & 0xFF; Status = FltGetVolumeName( pFltFileObj->Volume, &String1, &NumberOfBytes); } do { if ( Status != STATUS_SUCCESS) { if ( !String1.Buffer ) return 0; ExFreePoolWithTag( String1.Buffer, 'EPIP'); return 0; } RtlInitUnicodeString( &DestinationString, L"\\Device\\NamedPipe"); RtlInitUnicodeString( &String2, L"\\"); // жǷNampedPipe if ( RtlCompareUnicodeString( &String1, &DestinationString, 1) ) { if ( RtlCompareUnicodeString( &String1, &String2, 1) ) { ExFreePoolWithTag( String1.Buffer, 'EPIP'); return 0; } ExFreePoolWithTag( String1.Buffer, 'EPIP'); Type = 1;// 0ʾļ·1ʾ } else { ExFreePoolWithTag( String1.Buffer, 'EPIP'); Type = 2;// 2ʾܵ } } while (FALSE); return Type; } /**********************************************************************************/ #pragma LOCKEDCODE BOOL CSysmonBase::SysmonFileIsCommonName( PFLT_CALLBACK_DATA CallbackData ) { BOOL IsDirectory; PFLT_FILE_NAME_INFORMATION FileNameInformation; IsDirectory = 0; if ( CallbackData ) { if ( !CallbackData->Iopb->MajorFunction ) { FileNameInformation = 0; // #define FLT_FILE_NAME_NORMALIZED 0x01 // #define FLT_FILE_NAME_OPENED 0x02 // #define FLT_FILE_NAME_SHORT 0x03 // #define FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP 0x0400 if ( NT_SUCCESS(FltGetFileNameInformation( CallbackData, FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP | FLT_FILE_NAME_OPENED, &FileNameInformation)) ) { if ( NT_SUCCESS(FltParseFileNameInformation(FileNameInformation)) && !FileNameInformation->ParentDir.Length && !FileNameInformation->Share.Length && !FileNameInformation->FinalComponent.Length && !FileNameInformation->Extension.Length && FileNameInformation->Volume.Length ) { IsDirectory = 1; } FltReleaseFileNameInformation(FileNameInformation); } } } return IsDirectory; } /**********************************************************************************/ #pragma LOCKEDCODE bool CSysmonBase::SysmonQueryFileFileAttributes(PFLT_RELATED_OBJECTS pFltObj) { FILE_BASIC_INFORMATION FileBaseInfo; return NT_SUCCESS(FltQueryInformationFile( pFltObj->Instance, pFltObj->FileObject, &FileBaseInfo, sizeof(FileBaseInfo), FileBasicInformation, 0)) && !(FileBaseInfo.FileAttributes & (FILE_ATTRIBUTE_DEVICE| FILE_ATTRIBUTE_DIRECTORY)); } ================================================ FILE: Sysmon.sys/cpplib/CSysmonBase.h ================================================ #ifndef _CSysmonBase_h #define _CSysmonBase_h #include #include class CSysmonBase { public: CSysmonBase(void); ~CSysmonBase(void); public: static USHORT SysmonIsNamedPipe( PCFLT_RELATED_OBJECTS pFltFileObj ); static BOOL SysmonFileIsCommonName( PFLT_CALLBACK_DATA CallbackData ); static bool SysmonQueryFileFileAttributes( PFLT_RELATED_OBJECTS pFltObj ); }; #endif ================================================ FILE: Sysmon.sys/cpplib/CUnicodeString.cpp ================================================ #include "CUnicodeString.h" /**********************************************************************************/ #pragma LOCKEDCODE CUnicodeString::CUnicodeString(void) { mString.Buffer = NULL; mString.Length = 0; mString.MaximumLength = 0; } /**********************************************************************************/ #pragma LOCKEDCODE CUnicodeString::CUnicodeString(const CUnicodeString& String) { mString.Buffer = String.mString.Buffer; mString.Length = String.mString.Length; mString.MaximumLength = String.mString.MaximumLength; } /**********************************************************************************/ #pragma LOCKEDCODE CUnicodeString::CUnicodeString(const PUNICODE_STRING& pString) { if (pString) { __try { mString.Buffer = pString->Buffer; mString.Length = pString->Length; mString.MaximumLength = pString->MaximumLength; } __except(EXCEPTION_EXECUTE_HANDLER) { } } } /**********************************************************************************/ #pragma LOCKEDCODE CUnicodeString::~CUnicodeString(void) { } /**********************************************************************************/ #pragma LOCKEDCODE PUNICODE_STRING CUnicodeString::operator &() { return &mString; } /**********************************************************************************/ #pragma LOCKEDCODE CUnicodeString::operator PUNICODE_STRING() { return &mString; } /**********************************************************************************/ #pragma LOCKEDCODE void CUnicodeString::operator =(const WCHAR* pString) { if (pString) { RtlInitUnicodeString(&mString,pString); } } /**********************************************************************************/ #pragma LOCKEDCODE void CUnicodeString::operator =(WCHAR* pString) { if (pString) { RtlInitUnicodeString(&mString,pString); } } ================================================ FILE: Sysmon.sys/cpplib/CUnicodeString.h ================================================ #ifndef _CUnicodeString_h #define _CUnicodeString_h #include class CUnicodeString { public: CUnicodeString(void); CUnicodeString(const CUnicodeString& String); CUnicodeString(const PUNICODE_STRING& pString); virtual ~CUnicodeString(void); PUNICODE_STRING operator &(); operator PUNICODE_STRING(); void operator =(const WCHAR* pString); void operator =(WCHAR* pString); private: UNICODE_STRING mString; }; #endif ================================================ FILE: Sysmon.sys/cpplib/CVersion.cpp ================================================ #include "CVersion.h" CVersion::CVersion(void) :mMajorVersion(0) ,mMinorVersion(0) ,mBuildNumber(0) { } CVersion::~CVersion(void) { } /**********************************************************************************/ #pragma LOCKEDCODE void CVersion::GetOsVersion() { OSVERSIONINFOW VersionInformation; VersionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); if (NT_SUCCESS(::RtlGetVersion(&VersionInformation))) { mMajorVersion = VersionInformation.dwMajorVersion; mMinorVersion = VersionInformation.dwMinorVersion; } } /**********************************************************************************/ #pragma LOCKEDCODE void CVersion::PsGetVersion() { ::PsGetVersion(&mMajorVersion,&mMinorVersion, &mBuildNumber, 0); } /**********************************************************************************/ #pragma LOCKEDCODE ULONG CVersion::GetMajorVersion() { return mMajorVersion; } /**********************************************************************************/ #pragma LOCKEDCODE ULONG CVersion::GetMinorVersion() { return mMinorVersion; } /**********************************************************************************/ #pragma LOCKEDCODE ULONG CVersion::GetBuilderNumber() { return mBuildNumber; } ================================================ FILE: Sysmon.sys/cpplib/CVersion.h ================================================ #ifndef _CVersion_h #define _CVersion_h #include class CVersion { public: CVersion(void); ~CVersion(void); void GetOsVersion(); void PsGetVersion(); ULONG GetMajorVersion(); ULONG GetMinorVersion(); ULONG GetBuilderNumber(); private: ULONG mMajorVersion; ULONG mMinorVersion; ULONG mBuildNumber; ULONG mCSDVersion; }; #endif ================================================ FILE: Sysmon.sys/cpplib/CppLib.cpp ================================================ #include "CppLib.h" #include #include "CAssert.h" AtExitEntry *AtExitEntryList = NULL; // Exported variables #if defined(_IA64_) || defined(_AMD64_) #pragma section(".CRT$XCA",long,read) __declspec(allocate(".CRT$XCA")) void(*__ctors_begin__[1])(void) = { 0 }; #pragma section(".CRT$XCZ",long,read) __declspec(allocate(".CRT$XCZ")) void(*__ctors_end__[1])(void) = { 0 }; #pragma data_seg() #else #pragma data_seg(".CRT$XCA") void(*__ctors_begin__[1])(void) = { 0 }; #pragma data_seg(".CRT$XCZ") void(*__ctors_end__[1])(void) = { 0 }; #pragma data_seg() #endif #pragma data_seg(".STL$A") void(*___StlStartInitCalls__[1])(void) = { 0 }; #pragma data_seg(".STL$L") void(*___StlEndInitCalls__[1])(void) = { 0 }; #pragma data_seg(".STL$M") void(*___StlStartTerminateCalls__[1])(void) = { 0 }; #pragma data_seg(".STL$Z") void(*___StlEndTerminateCalls__[1])(void) = { 0 }; #pragma data_seg() #pragma data_seg(".CRT$XCA") PtrVoidFunc __xc_a[] = {NULL}; #pragma data_seg(".CRT$XCZ") PtrVoidFunc __xc_z[] = {NULL}; #pragma data_seg() // Functions EXTERN_C int __cdecl _cinit( __in int ) { for (void(**ctor)(void) = __ctors_begin__ + 1; ctor < __ctors_end__; ctor++) { (*ctor)(); } return 0; } int _cdecl atexit(PtrVoidFunc func) { AtExitEntry *newEntry; if (!func) { return 0; } newEntry = new AtExitEntry; if (IsNull(newEntry)) return 0; newEntry->func = func; newEntry->next = AtExitEntryList; AtExitEntryList = newEntry; return 1; } EXTERN_C void __cdecl doexit( __in int /*code*/, __in int /*quick*/, __in int /*retcaller*/ ) { for (AtExitEntry* entry = AtExitEntryList; entry;) { AtExitEntry* next = entry->next; delete entry; entry = next; } } void * NewHelper( size_t size, MemoryType memType) { CAssert(size); if ( size == 0 ) size = 1; // required by standard! //#if PGP_DEBUG void *pMem = ExAllocatePoolWithTag( (POOL_TYPE)memType, size, 'zpmt'); //#else // !PGPDISK_DEBUG //void *pMem = ExAllocatePool(NonPagedPool, size); //#endif // PGPDISK_DEBUG // #if PGP_DEBUG // if (IsntNull(pMem)) // pgpDebugWhackMemory(pMem, size); // #endif // PGP_DEBUG return pMem; }; void DeleteHelper(void *p) { if ( IsNull(p) ) ExFreePool(p); } void CallGlobalConstructors() { PtrVoidFunc *pfbegin, *pfend; pfbegin = __xc_a; pfend = __xc_z; while (pfbegin < pfend) { if (*pfbegin != NULL) (**pfbegin)(); ++pfbegin; } } void CallGlobalDestructors() { AtExitEntry *curEntry, *nextEntry; curEntry = AtExitEntryList; while (IsNull(curEntry)) { curEntry->func(); nextEntry = curEntry->next; delete curEntry; curEntry = nextEntry; } } //except EXCEPTION_DISPOSITION CxxFrameHandler3( __in void* pExcept, // Information for this exception __in ULONG_PTR RN, // Dynamic information for this frame __in void* pContext, // Context info __in void* pDC // More dynamic info for this frame ) { __debugbreak(); return EXCEPTION_DISPOSITION::ExceptionNestedException; } #ifdef _WIN64 extern "C" void _CxxThrowException( __in void *, __in _ThrowInfo * ) { } #else extern "C" void __stdcall _CxxThrowException( __in void *, __in _ThrowInfo * ) { } #endif type_info::type_info() { } type_info::~type_info() { } char const * type_info::name() const { return "N/A"; } bool type_info::operator==(type_info const & right) const { return false; } bool type_info::operator!=(type_info const & right) const { return false; } bool type_info::before(type_info const & right) const { return false; } type_info::type_info(type_info const & right) { } ================================================ FILE: Sysmon.sys/cpplib/CppLib.h ================================================ #ifndef _CPP_LIB_h #define _CPP_LIB_h #include #include typedef char CHAR; typedef unsigned char UCHAR; typedef unsigned char BOOLEAN; typedef wchar_t WCHAR; typedef unsigned char boolean; typedef unsigned __int32 UINT32; typedef unsigned int ULONG32, *PULONG32; typedef unsigned int DWORD32, *PDWORD32; typedef int BOOL; typedef signed char INT8, *PINT8; typedef signed short INT16, *PINT16; typedef signed int INT32, *PINT32; typedef signed __int64 INT64, *PINT64; typedef unsigned char UINT8, *PUINT8; typedef unsigned short UINT16, *PUINT16; typedef unsigned int UINT32, *PUINT32; typedef unsigned __int64 UINT64, *PUINT64; typedef __int64 INT64; typedef __int3264 ADDRPOINT; typedef __int3264 INT3264; typedef unsigned int UINT; typedef unsigned char BYTE; typedef unsigned long ULONG; typedef short SHORT; typedef unsigned short USHORT; #define IsNull(a) (a == NULL) #define PAGEDCODE code_seg("PAGE") #define LOCKEDCODE code_seg() #define INITCODE code_seg("INIT") #ifndef __cplusplus extern "C"{ #endif // Types typedef void (_cdecl *PtrVoidFunc)(void); struct AtExitEntry { PtrVoidFunc func; AtExitEntry *next; }; // Static variables int _cdecl atexit(PtrVoidFunc func); #ifndef __cplusplus }; #endif typedef enum MemoryType { kDefaultMemType = NonPagedPool, }; void * NewHelper( size_t size, MemoryType memType); void DeleteHelper(void *p); inline void* _cdecl operator new(size_t size) { return NewHelper(size,kDefaultMemType); } inline void * _cdecl operator new[](size_t size) { return NewHelper(size,kDefaultMemType); } inline void * _cdecl operator new(size_t size, MemoryType memType) { return NewHelper(size, memType); } inline void * _cdecl operator new[](size_t size, MemoryType memType) { return NewHelper(size, memType); } // Placement new. inline void * _cdecl operator new(size_t size, void *pMem) { (void) size; return pMem; } inline void * _cdecl operator new[](size_t size, void *pMem) { (void) size; return pMem; } // Operator delete functions inline void _cdecl operator delete(void *p) { DeleteHelper(p); } inline void _cdecl operator delete[](void *p) { DeleteHelper(p); } inline void _cdecl operator delete(void *p, MemoryType memType) { (void) memType; DeleteHelper(p); } inline void _cdecl operator delete[](void *p, MemoryType memType) { (void) memType; DeleteHelper(p); } // Placement delete. inline void _cdecl operator delete(void *pMem1, void *pMem2) { (void) pMem1; (void) pMem2; return; } inline void _cdecl operator delete[](void *pMem1, void *pMem2) { (void) pMem1; (void) pMem2; return; } void CallGlobalConstructors(); void CallGlobalDestructors(); extern "C" EXCEPTION_DISPOSITION CxxFrameHandler3( __in void* pExcept, // Information for this exception __in ULONG_PTR RN, // Dynamic information for this frame __in void* pContext, // Context info __in void* pDC // More dynamic info for this frame ); class type_info { public: type_info(); virtual ~type_info(); char const * name() const; bool operator==(type_info const & right) const; bool operator!=(type_info const & right) const; bool before(type_info const & right) const; private: type_info(type_info const & right); type_info & operator=(type_info const & right); }; #endif ================================================ FILE: Sysmon.sys/stdafx.cpp ================================================ // stdafx.cpp : source file that includes just the standard includes // Sysmon.sys.pch will be the pre-compiled header // stdafx.obj will contain the pre-compiled type information #include "stdafx.h" // TODO: reference any additional headers you need in STDAFX.H // and not in this file ================================================ FILE: Sysmon.sys/stdafx.h ================================================ // stdafx.h : include file for standard system include files, // or project specific include files that are used frequently, but // are changed infrequently // #pragma once #include "targetver.h" #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers // Windows Header Files: #include // TODO: reference additional headers your program requires here ================================================ FILE: Sysmon.sys/targetver.h ================================================ #pragma once // Including SDKDDKVer.h defines the highest available Windows platform. // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.