ListViewItem GetFilterMessage(FilterAPI.MessageSendData messageSend, ref string[] filterMessages) { ListViewItem lvItem = new ListViewItem(); try { string userName = string.Empty; string processName = string.Empty; FilterAPI.DecodeUserName(messageSend.Sid, out userName); FilterAPI.DecodeProcessName(messageSend.ProcessId, out processName); if ((messageSend.CreateOptions & (uint)WinData.CreateOptions.FO_REMOTE_ORIGIN) > 0) { //this is the request comes from remote server userName += ",remote access from network."; } string[] listData = new string[listView_Message.Columns.Count]; int col = 0; listData[col++] = messageSend.MessageId.ToString(); listData[col++] = FormatDateTime(messageSend.TransactionTime); listData[col++] = userName; listData[col++] = processName + " (" + messageSend.ProcessId + ")"; listData[col++] = messageSend.ThreadId.ToString(); listData[col++] = FormatIOName(messageSend); listData[col++] = messageSend.FileObject.ToString("X"); listData[col++] = messageSend.FileName; listData[col++] = messageSend.FileSize.ToString(); listData[col++] = ((FileAttributes)messageSend.FileAttributes).ToString(); listData[col++] = FormatDateTime(messageSend.LastWriteTime); listData[col++] = FormatStatus(messageSend.Status); listData[col++] = FormatDescription(messageSend); filterMessages = listData; lvItem = new ListViewItem(listData, 0); if (messageSend.Status >= (uint)NtStatus.Status.Error) { lvItem.BackColor = Color.LightGray; lvItem.ForeColor = Color.Red; } else if (messageSend.Status > (uint)NtStatus.Status.Warning) { lvItem.BackColor = Color.LightGray; lvItem.ForeColor = Color.Yellow; } } catch (Exception ex) { EventManager.WriteMessage(445, "GetFilterMessage", EventLevel.Error, "Add callback message failed." + ex.Message); lvItem = null; } return(lvItem); }
public void AddMessage(FilterAPI.MessageSendData messageSend) { lock (messageQueue) { if (messageQueue.Count > GlobalConfig.MaximumFilterMessages) { messageQueue.Clear(); } messageQueue.Enqueue(messageSend); } autoEvent.Set(); }
private static string FormatCreateDescription(FilterAPI.MessageSendData messageSend) { uint createOptions = messageSend.CreateOptions; uint desiredAccess = messageSend.DesiredAccess; uint dispositions = messageSend.Disposition; string message = string.Empty; message += "createOptions:"; foreach (REG_CREATE_OPTIONS createOption in Enum.GetValues(typeof(REG_CREATE_OPTIONS))) { if (createOption == (REG_CREATE_OPTIONS)((uint)createOption & createOptions)) { message += createOption.ToString() + "; "; } } message += "(0x" + createOptions.ToString("X") + ");\r\n"; message += "desiredAccess:"; foreach (REG_ACCESS_MASK accessMask in Enum.GetValues(typeof(REG_ACCESS_MASK))) { if (accessMask == (REG_ACCESS_MASK)((uint)accessMask & desiredAccess)) { message += accessMask.ToString() + "; "; } } message += "(0x" + desiredAccess.ToString("X") + ");\r\n"; if (dispositions > 0) { message += "dispositions:"; foreach (REG_DISPOSITION disposition in Enum.GetValues(typeof(REG_DISPOSITION))) { if (disposition == (REG_DISPOSITION)((uint)disposition & dispositions)) { message += disposition.ToString() + "; "; } } message += "(0x" + desiredAccess.ToString("X") + ");"; } return(message); }
/// <summary> /// convert the secure share file's embedded DRM data to encrypted file's meta data with the attached tag. /// </summary> /// <param name="messageSend"></param> private void ProcessSecuredSharedFile(FilterAPI.MessageSendData messageSend) { string lastError = string.Empty; if (!DigitalRightControl.ProcessSecureShareFile(messageSend.FileName, out lastError)) { if (!retryFiles.ContainsKey(messageSend.FileName)) { retryFiles.Add(messageSend.FileName, 0); } EventManager.WriteMessage(147, "ProcessSecureShareFile", EventLevel.Error, lastError); } else { EventManager.WriteMessage(159, "ProcessSecureShareFile", EventLevel.Verbose, "Process secure file " + messageSend.FileName + " succeeded."); } }
public void AddMessage(FilterAPI.MessageSendData messageSend) { lock (messageQueue) { if (messageQueue.Count > GlobalConfig.MaximumFilterMessages) { messageQueue.Clear(); } if (messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_SEND_PROCESS_CREATION_INFO || messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_SEND_PROCESS_TERMINATION_INFO || messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_SEND_THREAD_CREATION_INFO || messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_SEND_THREAD_TERMINATION_INFO) { //this is the process filter command, we don't display the message. return; } messageQueue.Enqueue(messageSend); } autoEvent.Set(); }
public static string FormatIOName(FilterAPI.MessageSendData messageSend) { string ioName = string.Empty; try { if (messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_SEND_FILE_CHANGED_EVENT) { foreach (FilterAPI.EVENTTYPE eventType in Enum.GetValues(typeof(FilterAPI.EVENTTYPE))) { if (eventType != FilterAPI.EVENTTYPE.NONE && ((messageSend.InfoClass & (uint)eventType) > 0)) { if (ioName.Length > 0) { ioName = ioName + " ," + eventType.ToString(); } else { ioName = eventType.ToString(); } } } } else if (messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_REQUEST_USER_PERMIT || messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_REQUEST_ENCRYPTION_IV_AND_KEY) { ioName = "REQUEST_ACCESS_PERMISSION"; } else if (messageSend.MessageType == (uint)FilterAPI.MessageType.PRE_QUERY_INFORMATION) { if (messageSend.FsContext.ToInt64() == 0) { ioName = "PRE_FASTIO_NETWORK_QUERY_OPEN"; } else { ioName = "PRE_QUERY_INFORMATION"; } } else if (messageSend.MessageType == (uint)FilterAPI.MessageType.POST_QUERY_INFORMATION) { if (messageSend.FsContext.ToInt64() == 0) { ioName = "POST_FASTIO_NETWORK_QUERY_OPEN"; } else { ioName = "POST_QUERY_INFORMATION"; } } else { ioName = ((FilterAPI.MessageType)messageSend.MessageType).ToString(); } } catch (Exception ex) { EventManager.WriteMessage(592, "FormatIOName", EventLevel.Error, "Get IO name from " + messageSend.MessageType.ToString("X") + " exception:" + ex.Message); } if (ioName.Trim().Length == 0) { ioName = "UnKnown IO Type (0x" + messageSend.MessageType.ToString("X") + ")"; } return(ioName); }
string FormatDescription(FilterAPI.MessageSendData messageSend) { string message = string.Empty; try { if (messageSend.Status == (uint)NtStatus.Status.Success) { if (messageSend.MessageType == (uint)FilterAPI.FilterCommand.FILTER_SEND_FILE_CHANGED_EVENT && messageSend.InfoClass == (uint)FilterAPI.EVENTTYPE.RENAMED) { string newFileName = string.Empty; if (messageSend.DataBufferLength > 0) { byte[] buffer = new byte[messageSend.DataBufferLength]; Array.Copy(messageSend.DataBuffer, buffer, buffer.Length); newFileName = Encoding.Unicode.GetString(buffer); } message = "File " + messageSend.FileName + " was renamed to " + newFileName; return(message); } } else { return(message); } switch ((FilterAPI.MessageType)messageSend.MessageType) { case FilterAPI.MessageType.POST_CREATE: { if ((messageSend.CreateOptions & (uint)WinData.CreateOptions.FILE_DELETE_ON_CLOSE) > 0) { message = "file was marked as deleted."; } if (messageSend.Status == (uint)NtStatus.Status.Success) { //the create status is meaningful only when the status is succeeded. message += "CreateStatus:" + ((WinData.CreateStatus)messageSend.CreateStatus).ToString(); } message += " DesiredAccess:" + FormatDesiredAccess(messageSend.DesiredAccess); message += " Disposition:" + ((WinData.Disposition)messageSend.Disposition).ToString(); message += " ShareAccess:" + ((WinData.ShareAccess)messageSend.SharedAccess).ToString(); message += " CreateOptions:" + FormatCreateOptions(messageSend.CreateOptions); break; } case FilterAPI.MessageType.POST_CACHE_READ: case FilterAPI.MessageType.POST_FASTIO_READ: case FilterAPI.MessageType.POST_NOCACHE_READ: case FilterAPI.MessageType.POST_PAGING_IO_READ: { message = "read offset:" + messageSend.Offset + " length:" + messageSend.Length; //read data is here //messageSend.DataBufferLength, messageSend.DataBuffer break; } case FilterAPI.MessageType.POST_CACHE_WRITE: case FilterAPI.MessageType.POST_FASTIO_WRITE: case FilterAPI.MessageType.POST_NOCACHE_WRITE: case FilterAPI.MessageType.POST_PAGING_IO_WRITE: { message = "write offset:" + messageSend.Offset + " length:" + messageSend.Length; //written data is here //messageSend.DataBufferLength, messageSend.DataBuffer break; } case FilterAPI.MessageType.POST_SET_INFORMATION: { message = FormatInformationDataBuffer((WinData.FileInfomationClass)messageSend.InfoClass, messageSend.DataBufferLength, messageSend.DataBuffer); break; } case FilterAPI.MessageType.POST_QUERY_INFORMATION: { message = FormatInformationDataBuffer((WinData.FileInfomationClass)messageSend.InfoClass, messageSend.DataBufferLength, messageSend.DataBuffer); break; } case FilterAPI.MessageType.POST_SET_SECURITY: { message = "set security with information class:" + FormatSecurityInfoClass(messageSend.InfoClass); break; } case FilterAPI.MessageType.POST_QUERY_SECURITY: { message = "query security with information class:" + FormatSecurityInfoClass(messageSend.InfoClass); break; } case FilterAPI.MessageType.POST_DIRECTORY: { message = "browse directory with information class:" + ((WinData.FileInfomationClass)messageSend.InfoClass).ToString(); break; } case FilterAPI.MessageType.POST_CLEANUP: { message = "all file handles to fileObject " + messageSend.FileObject.ToString("X") + " were closed."; break; } case FilterAPI.MessageType.POST_CLOSE: { message = "all system references to fileObject " + messageSend.FileObject.ToString("X") + " were closed."; break; } } } catch (Exception ex) { EventManager.WriteMessage(318, "FormatDescription", EventLevel.Error, "Format description failed with error " + ex.Message); } return(message); }
public static bool AuthorizeFileAccess(FilterAPI.MessageSendData messageSend, ref FilterAPI.MessageReplyData messageReply) { bool ret = true; try { messageReply.MessageId = messageSend.MessageId; messageReply.MessageType = messageSend.MessageType; messageReply.ReturnStatus = (uint)FilterAPI.NTSTATUS.STATUS_SUCCESS; messageReply.MessageId = messageSend.MessageId; messageReply.MessageType = messageSend.MessageType; // //here you can control all the registered IO requests,block the access or modify the I/O data base on the file IO information from MessageSend struture // // //if you don't want to change anything to this IO request, just let it pass through as below setting: //messageReply.FilterStatus = 0; //messageReply.ReturnStatus = (uint)NtStatus.Status.Success; //if you want to block the access this IO request before it goes down to the file system, you can return the status as below, //it is only for pre IO requests, it means the user IO reuqests will be completed here instead of going down to the file system. //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; //messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; //if you want to modify the IO data and complete the pre IO with your own data, you can return status as below: // messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; // messageReply.DataBufferLength = the return data buffer length. // messageReply.DataBuffer = the data you want to return. // messageReply.ReturnStatus = (uint)NtStatus.Status.Success; FilterAPI.MessageType messageType = (FilterAPI.MessageType)messageSend.MessageType; WinData.FileInfomationClass infoClass = (WinData.FileInfomationClass)messageSend.InfoClass; uint dataLength = messageSend.DataBufferLength; byte[] data = messageSend.DataBuffer; //here is some IO information for your reference: if ((messageSend.CreateOptions & (uint)WinData.CreateOptions.FO_REMOTE_ORIGIN) > 0) { //this is file access request comes from remote network server } //you can check the file create option with this data: //"DesiredAccess: messageSend.DesiredAccess //"Disposition:" + ((WinData.Disposition)messageSend.Disposition).ToString(); //"ShareAccess:" + ((WinData.ShareAccess)messageSend.SharedAccess).ToString(); //"CreateOptions:"messageSend.CreateOptions //Here is the demo to copy file content before it was deleted.----------------------------------------------- bool isFileDeleting = false; if (messageSend.Status == (uint)NtStatus.Status.Success) { if (messageType == FilterAPI.MessageType.POST_CREATE) { if ((messageSend.CreateOptions & (uint)WinData.CreateOptions.FILE_DELETE_ON_CLOSE) > 0) { isFileDeleting = true; } } else if (messageType == FilterAPI.MessageType.PRE_SET_INFORMATION) { if (infoClass == WinData.FileInfomationClass.FileDispositionInformation) { isFileDeleting = true; } } if (isFileDeleting) { //IntPtr fileHandle = IntPtr.Zero; //bool retVal = FilterAPI.GetFileHandleInFilter(messageSend.FileName,(uint)FileAccess.Read, ref fileHandle); //if (retVal) //{ // SafeFileHandle sHandle = new SafeFileHandle(fileHandle, true); // FileStream fileStream = new FileStream(sHandle, FileAccess.Read); // //copy your data here... // fileStream.Close(); //} } } //End ----------------------------------------------- switch (messageType) { case FilterAPI.MessageType.PRE_CREATE: { //here you reparse the file open to another new file name //string newReparseFileName = "\\??\\c:\\myNewFile.txt"; //byte[] returnData = Encoding.Unicode.GetBytes(newReparseFileName); //Array.Copy(returnData, messageReply.DataBuffer, returnData.Length); //messageReply.DataBufferLength = (uint)returnData.Length; //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; //messageReply.ReturnStatus = (uint)NtStatus.Status.Reparse; break; } case FilterAPI.MessageType.PRE_CACHE_READ: case FilterAPI.MessageType.POST_CACHE_READ: case FilterAPI.MessageType.PRE_NOCACHE_READ: case FilterAPI.MessageType.POST_NOCACHE_READ: case FilterAPI.MessageType.PRE_PAGING_IO_READ: case FilterAPI.MessageType.POST_PAGING_IO_READ: case FilterAPI.MessageType.PRE_CACHE_WRITE: case FilterAPI.MessageType.POST_CACHE_WRITE: case FilterAPI.MessageType.PRE_NOCACHE_WRITE: case FilterAPI.MessageType.POST_NOCACHE_WRITE: case FilterAPI.MessageType.PRE_PAGING_IO_WRITE: case FilterAPI.MessageType.POST_PAGING_IO_WRITE: { //byte[] returnData = //new data you want to modify the read/write data; //Array.Copy(returnData, messageReply.DataBuffer, returnData.Length); //messageReply.DataBufferLength = (uint)returnData.Length; ////for pre IO,use this one //// messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; // messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; // messageReply.ReturnStatus = (uint)NtStatus.Status.Success; break; } case FilterAPI.MessageType.PRE_SET_INFORMATION: case FilterAPI.MessageType.POST_SET_INFORMATION: case FilterAPI.MessageType.PRE_QUERY_INFORMATION: case FilterAPI.MessageType.POST_QUERY_INFORMATION: { switch (infoClass) { case WinData.FileInfomationClass.FileRenameInformation: { if (FilterAPI.MessageType.PRE_SET_INFORMATION == messageType) { string blockFileName = @"c:\filterTest\blockRename.txt"; //test block rename to blockFileName, it needs to register PRE_SET_INFORMATION; if (string.Compare(messageSend.FileName, blockFileName, true) == 0) { EventManager.WriteMessage(179, "IOAccessControl", EventLevel.Warning, "Block rename for file:" + messageSend.FileName); ret = false; break; } } //you can block file rename as below //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; //messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; break; } case WinData.FileInfomationClass.FileDispositionInformation: { //you can block file delete as below //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; //messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; break; } case WinData.FileInfomationClass.FileEndOfFileInformation: { //change file size break; } case WinData.FileInfomationClass.FileBasicInformation: { //file basic information break; } case WinData.FileInfomationClass.FileStandardInformation: { //file standard information break; } case WinData.FileInfomationClass.FileNetworkOpenInformation: { //file network information break; } case WinData.FileInfomationClass.FileInternalInformation: { //file internal inofrmation break; } default: { break; } } break; } } } catch (Exception ex) { EventManager.WriteMessage(174, "IOAccessControl", EventLevel.Error, "IOAccessControl failed." + ex.Message); } return(ret); }
ListViewItem GetFilterMessage(FilterAPI.MessageSendData messageSend, ref string[] filterMessages) { ListViewItem lvItem = new ListViewItem(); try { string userName = string.Empty; string processName = string.Empty; FilterAPI.DecodeUserName(messageSend.Sid, out userName); FilterAPI.DecodeProcessName(messageSend.ProcessId, out processName); if ((messageSend.CreateOptions & (uint)WinData.CreateOptions.FO_REMOTE_ORIGIN) > 0) { //this is the request comes from remote server string remoteIp = string.Empty; if (messageSend.DataBufferLength > 0 && ((uint)FilterAPI.MessageType.POST_CREATE == messageSend.MessageType)) { byte[] buffer = new byte[messageSend.DataBufferLength]; Array.Copy(messageSend.DataBuffer, buffer, buffer.Length); remoteIp = Encoding.Unicode.GetString(buffer); userName += ",RemoteIP:" + remoteIp; } else { userName += ",Accessed from remote computer."; } } string[] listData = new string[listView_Message.Columns.Count]; int col = 0; listData[col++] = messageSend.MessageId.ToString(); listData[col++] = FormatDateTime(messageSend.TransactionTime); listData[col++] = userName; listData[col++] = processName + " (" + messageSend.ProcessId + ")"; listData[col++] = messageSend.ThreadId.ToString(); listData[col++] = FormatIOName(messageSend); listData[col++] = messageSend.FileObject.ToString("X"); listData[col++] = messageSend.FileName; listData[col++] = messageSend.FileSize.ToString(); listData[col++] = ((FileAttributes)messageSend.FileAttributes).ToString(); listData[col++] = FormatDateTime(messageSend.LastWriteTime); listData[col++] = FormatStatus(messageSend.Status); listData[col++] = FormatDescription(messageSend); filterMessages = listData; lvItem = new ListViewItem(listData, 0); if (messageSend.Status >= (uint)NtStatus.Status.Error) { lvItem.BackColor = Color.LightGray; lvItem.ForeColor = Color.Red; } else if (messageSend.Status > (uint)NtStatus.Status.Warning) { lvItem.BackColor = Color.LightGray; lvItem.ForeColor = Color.Yellow; } } catch (Exception ex) { EventManager.WriteMessage(445, "GetFilterMessage", EventLevel.Error, "Add callback message failed." + ex.Message); lvItem = null; } return(lvItem); }
public static bool AuthorizeRegistryAccess(FilterAPI.MessageSendData messageSend, ref FilterAPI.MessageReplyData messageReply) { bool ret = true; try { messageReply.MessageId = messageSend.MessageId; messageReply.MessageType = messageSend.MessageType; messageReply.ReturnStatus = (uint)FilterAPI.NTSTATUS.STATUS_SUCCESS; // //here you can control registry request,block the access or modify the registry data. // // //if you don't want to change anything to this registry request, just let it pass through as below setting: //messageReply.FilterStatus = 0; //messageReply.ReturnStatus = (uint)NtStatus.Status.Success; //if you want to block the access this registry request, you can return the status as below, //it is only for pre callback requests. //messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; //messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; //if you want to modify the registry data and complete the pre IO with your own data, you can return status as below: // messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; // messageReply.DataBufferLength = the return data buffer length. // messageReply.DataBuffer = the data you want to return. // messageReply.ReturnStatus = (uint)NtStatus.Status.Success; FilterAPI.RegCallbackClass regCallbackClass = (FilterAPI.RegCallbackClass)messageSend.Offset; uint dataLength = messageSend.DataBufferLength; byte[] data = messageSend.DataBuffer; switch (regCallbackClass) { case FilterAPI.RegCallbackClass.Reg_Pre_Query_Value_Key: { KEY_VALUE_INFORMATION_CLASS keyValuseInformationClass = (KEY_VALUE_INFORMATION_CLASS)messageSend.InfoClass; IntPtr keyValueInfoPtr = Marshal.UnsafeAddrOfPinnedArrayElement(data, 0); if (messageSend.FileName.IndexOf("EaseFilter") <= 0) { //this is not our unit test key break; } //below code is for unit test to demo how to complete pre-callback registry call with our own data. EventManager.WriteMessage(400, "AuthorizeRegistryAccess", EventLevel.Error, "Reg_Pre_Query_Value_Key keyValuseInformationClass:" + keyValuseInformationClass.ToString()); switch (keyValuseInformationClass) { case KEY_VALUE_INFORMATION_CLASS.KeyValueBasicInformation: { //public struct KEY_VALUE_BASIC_INFORMATION // { // public uint TitleIndex; // public uint Type; // public uint NameLength; // public byte[] Name; // } uint titleIndex = 0; uint type = (uint)VALUE_DATA_TYPE.REG_DWORD; byte[] valueName = Encoding.Unicode.GetBytes("value1"); uint valueNameLength = (uint)valueName.Length; MemoryStream ms = new MemoryStream(messageReply.DataBuffer); BinaryWriter bw = new BinaryWriter(ms); bw.Write(titleIndex); bw.Write(type); bw.Write(valueNameLength); bw.Write(valueName); messageReply.DataBufferLength = (uint)ms.Position; messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; break; } case KEY_VALUE_INFORMATION_CLASS.KeyValueFullInformation: { //KeyValueFullInformation class structure //public uint TitleIndex; //public uint Type; //public uint DataOffset; //public uint DataLength; //public uint NameLength; //public byte[] Name; uint titleIndex = 0; uint type = (uint)VALUE_DATA_TYPE.REG_DWORD; uint testData = 12345; uint testDataLength = sizeof(uint); byte[] valueName = Encoding.Unicode.GetBytes("value1"); uint valueNameLength = (uint)valueName.Length; uint dataOffset = 5 * sizeof(uint) + valueNameLength; MemoryStream ms = new MemoryStream(messageReply.DataBuffer); BinaryWriter bw = new BinaryWriter(ms); bw.Write(titleIndex); bw.Write(type); bw.Write(dataOffset); bw.Write(testDataLength); bw.Write(valueNameLength); bw.Write(valueName); bw.Write(testData); messageReply.DataBufferLength = (uint)ms.Position; messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; break; } case KEY_VALUE_INFORMATION_CLASS.KeyValuePartialInformation: { // public struct KEY_VALUE_PARTIAL_INFORMATION //{ // public uint TitleIndex; // public uint Type; // public uint DataLength; // public byte[] Data; //} uint titleIndex = 0; uint type = (uint)VALUE_DATA_TYPE.REG_DWORD; uint testData = 12345; uint testDataLength = sizeof(uint); MemoryStream ms = new MemoryStream(messageReply.DataBuffer); BinaryWriter bw = new BinaryWriter(ms); bw.Write(titleIndex); bw.Write(type); bw.Write(testDataLength); bw.Write(testData); messageReply.DataBufferLength = (uint)ms.Position; messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION | (uint)FilterAPI.FilterStatus.FILTER_DATA_BUFFER_IS_UPDATED; messageReply.ReturnStatus = (uint)FilterAPI.NTSTATUS.STATUS_SUCCESS; break; } default: break; } break; } case FilterAPI.RegCallbackClass.Reg_Pre_Create_KeyEx: case FilterAPI.RegCallbackClass.Reg_Pre_Open_KeyEx: { //this is our unit test key if (messageSend.FileName.IndexOf("EaseFilter") > 0) { //NOT allow to create new registry key. messageReply.FilterStatus = (uint)FilterAPI.FilterStatus.FILTER_COMPLETE_PRE_OPERATION; messageReply.ReturnStatus = (uint)NtStatus.Status.AccessDenied; } break; } default: break; } } catch (Exception ex) { EventManager.WriteMessage(400, "AuthorizeRegistryAccess", EventLevel.Error, "AuthorizeRegistryAccess exception:" + ex.Message); } return(ret); }
public static string FormatDescription(FilterAPI.MessageSendData messageSend) { string descrption = string.Empty; FilterAPI.RegCallbackClass regCallbackClass = (FilterAPI.RegCallbackClass)messageSend.Offset; try { if (messageSend.Status != (uint)FilterAPI.NTSTATUS.STATUS_SUCCESS) { return(""); } switch (regCallbackClass) { case FilterAPI.RegCallbackClass.Reg_Pre_Delete_Key: case FilterAPI.RegCallbackClass.Reg_Post_Delete_Key: { descrption = "registry key is being deleted."; break; } case FilterAPI.RegCallbackClass.Reg_Pre_Set_Value_Key: case FilterAPI.RegCallbackClass.Reg_Post_Set_Value_Key: { VALUE_DATA_TYPE valueType = (VALUE_DATA_TYPE)messageSend.InfoClass; descrption = "Type:" + valueType.ToString(); descrption += " Data:" + ValueTypeData(valueType, (int)messageSend.DataBufferLength, messageSend.DataBuffer); break; } case FilterAPI.RegCallbackClass.Reg_Pre_Delete_Value_Key: case FilterAPI.RegCallbackClass.Reg_Post_Delete_Value_Key: { descrption = "registry key's value is being deleted."; break; } case FilterAPI.RegCallbackClass.Reg_Pre_SetInformation_Key: case FilterAPI.RegCallbackClass.Reg_Post_SetInformation_Key: { KEY_SET_INFORMATION_CLASS keySetInformationClass = (KEY_SET_INFORMATION_CLASS)messageSend.InfoClass; descrption = keySetInformationClass.ToString(); break; } case FilterAPI.RegCallbackClass.Reg_Pre_Rename_Key: case FilterAPI.RegCallbackClass.Reg_Post_Rename_Key: { string newName = Encoding.Unicode.GetString(messageSend.DataBuffer); descrption = "registry key's name is being changed to " + newName; break; } case FilterAPI.RegCallbackClass.Reg_Pre_Enumerate_Key: { KEY_INFORMATION_CLASS keyInformationClass = (KEY_INFORMATION_CLASS)messageSend.InfoClass; descrption = keyInformationClass.ToString(); break; } case FilterAPI.RegCallbackClass.Reg_Post_Enumerate_Key: { KEY_INFORMATION_CLASS keyInformationClass = (KEY_INFORMATION_CLASS)messageSend.InfoClass; descrption += KeyInformation(keyInformationClass, messageSend.DataBuffer); break; } case FilterAPI.RegCallbackClass.Reg_Pre_Enumerate_Value_Key: { KEY_VALUE_INFORMATION_CLASS keyValuseInformationClass = (KEY_VALUE_INFORMATION_CLASS)messageSend.InfoClass; descrption = keyValuseInformationClass.ToString(); break; } case FilterAPI.RegCallbackClass.Reg_Post_Enumerate_Value_Key: { KEY_VALUE_INFORMATION_CLASS keyValuseInformationClass = (KEY_VALUE_INFORMATION_CLASS)messageSend.InfoClass; descrption += KeyValueInformation(keyValuseInformationClass, messageSend.DataBuffer); break; } case FilterAPI.RegCallbackClass.Reg_Pre_Query_Key: { KEY_INFORMATION_CLASS keyInformationClass = (KEY_INFORMATION_CLASS)messageSend.InfoClass; descrption = keyInformationClass.ToString(); break; } case FilterAPI.RegCallbackClass.Reg_Post_Query_Key: { KEY_INFORMATION_CLASS keyInformationClass = (KEY_INFORMATION_CLASS)messageSend.InfoClass; descrption += KeyInformation(keyInformationClass, messageSend.DataBuffer); break; } case FilterAPI.RegCallbackClass.Reg_Pre_Query_Value_Key: { KEY_VALUE_INFORMATION_CLASS keyValuseInformationClass = (KEY_VALUE_INFORMATION_CLASS)messageSend.InfoClass; descrption = keyValuseInformationClass.ToString(); break; } case FilterAPI.RegCallbackClass.Reg_Post_Query_Value_Key: { //for unit test if (messageSend.FileName.IndexOf("EaseFilter") > 0) { //this is our test key. RegistryUnitTest.postQueryValueKeyPassed = true; } KEY_VALUE_INFORMATION_CLASS keyValuseInformationClass = (KEY_VALUE_INFORMATION_CLASS)messageSend.InfoClass; descrption += KeyValueInformation(keyValuseInformationClass, messageSend.DataBuffer); break; } case FilterAPI.RegCallbackClass.Reg_Pre_Query_Multiple_Value_Key: { break; } case FilterAPI.RegCallbackClass.Reg_Post_Query_Multiple_Value_Key: { uint entryCount = messageSend.InfoClass; MemoryStream ms = new MemoryStream(messageSend.DataBuffer); BinaryReader br = new BinaryReader(ms); for (int i = 0; i < entryCount && ms.Position < ms.Length; i++) { long currentOffset = ms.Position; int nextEntryOffset = br.ReadInt32(); int valueNameLength = br.ReadInt32(); int dataType = br.ReadInt32(); int dataLength = br.ReadInt32(); byte[] valueName = br.ReadBytes(valueNameLength); byte[] data = br.ReadBytes(dataLength); VALUE_DATA_TYPE type = (VALUE_DATA_TYPE)dataType; descrption += "Name:" + Encoding.Unicode.GetString(valueName, 0, valueNameLength); descrption += " Type:" + type.ToString(); descrption += " Data:" + ValueTypeData(type, dataLength, data) + Environment.NewLine; ms.Position = currentOffset + nextEntryOffset; } break; } case FilterAPI.RegCallbackClass.Reg_Pre_Create_KeyEx: case FilterAPI.RegCallbackClass.Reg_Post_Create_KeyEx: case FilterAPI.RegCallbackClass.Reg_Pre_Open_KeyEx: case FilterAPI.RegCallbackClass.Reg_Post_Open_KeyEx: { descrption += FormatCreateDescription(messageSend); break; } case FilterAPI.RegCallbackClass.Reg_Pre_Load_Key: case FilterAPI.RegCallbackClass.Reg_Post_Load_Key: { descrption += "SourceFile:" + Encoding.Unicode.GetString(messageSend.DataBuffer, 0, (int)messageSend.DataBufferLength); break; } case FilterAPI.RegCallbackClass.Reg_Pre_Replace_Key: case FilterAPI.RegCallbackClass.Reg_Post_Replace_Key: { descrption += "NewFileName:" + Encoding.Unicode.GetString(messageSend.DataBuffer, 0, (int)messageSend.DataBufferLength); break; } case FilterAPI.RegCallbackClass.Reg_Pre_Query_KeyName: case FilterAPI.RegCallbackClass.Reg_Post_Query_KeyName: { break; } default: descrption = "unsupported registry callback class:" + regCallbackClass.ToString(); break; } } catch (Exception ex) { descrption = "Format description failed, return error:" + ex.Message; } return(descrption); }