///////////////////////////////////////////////////// // // // DoKernelModeHeuristics() // // // ///////////////////////////////////////////////////// //Description: Communicates with kernel-mode driver // to perform advanced heuristic analysis. // (oooo...aaaahhh) // //Returns: true if successful ////////////////////////////////////////////////////// private unsafe bool DoKernelModeHeuristics() { AgentHeuristicMatches.KernelModeMatches = new CwXML.KernelModeHeuristicMatches(); AgentScanLog.AppendLine(""); AgentScanLog.AppendLine("*********************************************"); AgentScanLog.AppendLine(" KERNEL-MODE HEURISTICS "); AgentScanLog.AppendLine("*********************************************"); AgentScanLog.AppendLine(""); //---------------------------------------------- // // SSDT HOOKS // //---------------------------------------------- #region SSDT HOOKS if (AgentSettings["KernelHeuristics_SSDT_DetectHooks"] == "True") { AgentScanLog.AppendLine("------------------------"); AgentScanLog.AppendLine(" SSDT HOOKS "); AgentScanLog.AppendLine("------------------------"); CwStructures.HOOKED_SSDT_TABLE HookTable = new CwStructures.HOOKED_SSDT_TABLE(); try { HookTable = HeuristicsKernelModeHelper.GetSSDTHooks(); } catch (Exception ex) { AgentScanLog.AppendLine("SCAN: Error checking for SSDT hooks: " + ex.Message); } //save the hook table to return object. AgentHeuristicMatches.KernelModeMatches.SSDTHookTable = HookTable; } else { AgentHeuristicMatches.KernelModeMatches.SSDTHookTable = new CwStructures.HOOKED_SSDT_TABLE(); } #endregion //---------------------------------------------- // // SSDT DETOURS // //---------------------------------------------- #region SSDT DETOURS if (AgentSettings["KernelHeuristics_SSDT_DetectDetours"] == "True") { AgentScanLog.AppendLine("------------------------"); AgentScanLog.AppendLine(" SSDT DETOURS "); AgentScanLog.AppendLine("------------------------"); CwStructures.DETOURED_SSDT_TABLE DetourTable = new CwStructures.DETOURED_SSDT_TABLE(); try { DetourTable = HeuristicsKernelModeHelper.GetSSDTDetours(); } catch (Exception ex) { AgentScanLog.AppendLine("SCAN: Error checking for SSDT detours: " + ex.Message); } //save the hook table to return object. AgentHeuristicMatches.KernelModeMatches.SSDTDetourTable = DetourTable; } else { AgentHeuristicMatches.KernelModeMatches.SSDTDetourTable = new CwStructures.DETOURED_SSDT_TABLE(); } #endregion //---------------------------------------------- // // WIN32 API DETOURS // //---------------------------------------------- // //TODO: this functionality is disabled until fixed. // #region WIN32 API DETOURS /* if (AgentSettings["KernelHeuristics_Win32Api_CheckExportsForDetours"] == "True") { AgentScanLog.AppendLine("------------------------"); AgentScanLog.AppendLine(" WIN32 API DETOURS "); AgentScanLog.AppendLine("------------------------"); string[] DirtyDlls = new string[] { "ntdll.dll","kernel32.dll","user32.dll","advapi32.dll", "gdi32.dll","comdlg32.dll","comctl32.dll","commctrl.dll", "shell.dll","shlwapi.dll","mshtml.dll","urlmon.dll"}; //ntdll.dll?? //initialize return object to 12 items AgentHeuristicMatches.KernelModeMatches.Win32DetourTable = new CwStructures.WIN32API_DETOUR_TABLE[12]; //loop through DLLs we care about for (int i = 0; i < DirtyDlls.Length; i++) { CwStructures.WIN32API_DETOUR_TABLE ModuleDetourTable = new CwStructures.WIN32API_DETOUR_TABLE(); string thisDLL = DirtyDlls[i]; try { ModuleDetourTable = HeuristicsKernelModeHelper.GetModuleDetours(thisDLL); } catch (Exception ex) { AgentScanLog.AppendLine("SCAN: Error checking for detours in module '" + thisDLL + "': " + ex.Message); continue; } //save the hook table to return object. AgentHeuristicMatches.KernelModeMatches.Win32DetourTable[i] = ModuleDetourTable; } } else { AgentHeuristicMatches.KernelModeMatches.Win32DetourTable = new CwStructures.WIN32API_DETOUR_TABLE[0]; } */ #endregion //---------------------------------------------- // // IRP HOOKS // //---------------------------------------------- #region IRP HOOOKS if (AgentSettings["DriversHeuristics_DetectIRPHooks"] == "True" && AgentSettings.ContainsKey("AddDriverListview")) { //get the list of driver names and objects //it is stored in the settings variable "AddDriverListview" //as a comma-separated list: // string[]= {driver1,device1,driver2,device2,..} string drivers = AgentSettings["AddDriverListview"]; if (drivers.IndexOf(",") != -1) { //values were stored as comma-separated list string[] items = drivers.Split(new char[] { ',' }); //get DRIVER_CHECK_INFO structs from the driver/device pairs ArrayList driversToCheck = DriverHelper.GetDriverInfoStructs(items); //bail completely if (driversToCheck == null) { AgentHeuristicMatches.KernelModeMatches.DriverIrpHooksTable = new CwStructures.HOOKED_DISPATCH_FUNCTIONS_TABLE[0]; return false; } AgentScanLog.AppendLine("------------------------"); AgentScanLog.AppendLine(" IRP HOOKS "); AgentScanLog.AppendLine("------------------------"); AgentHeuristicMatches.KernelModeMatches.DriverIrpHooksTable = new CwStructures.HOOKED_DISPATCH_FUNCTIONS_TABLE[driversToCheck.Count]; int count = 0; //loop through all drivers/device name combinations supplied by user and check for IRP hooks foreach (CwStructures.DRIVER_CHECK_INFO thisDriver in (CwStructures.DRIVER_CHECK_INFO[])driversToCheck.ToArray(typeof(CwStructures.DRIVER_CHECK_INFO))) { CwStructures.HOOKED_DISPATCH_FUNCTIONS_TABLE DriverHookTable = new CwStructures.HOOKED_DISPATCH_FUNCTIONS_TABLE(); try { DriverHookTable = HeuristicsKernelModeHelper.GetHookedDispatchFunctionsInDriver(thisDriver); } catch (Exception ex) { AgentScanLog.AppendLine("SCAN: Error checking for IRP hooks: " + ex.Message); } AgentHeuristicMatches.KernelModeMatches.DriverIrpHooksTable[count] = DriverHookTable; count++; } } else { AgentHeuristicMatches.KernelModeMatches.DriverIrpHooksTable = new CwStructures.HOOKED_DISPATCH_FUNCTIONS_TABLE[0]; } } else { AgentHeuristicMatches.KernelModeMatches.DriverIrpHooksTable = new CwStructures.HOOKED_DISPATCH_FUNCTIONS_TABLE[0]; } #endregion //---------------------------------------------- // // IRP DETOURS // //---------------------------------------------- #region IRP DETOURS if (AgentSettings["DriversHeuristics_CheckDispatchRoutinesForDetours"] == "True" && AgentSettings.ContainsKey("AddDriverListview")) { //get the list of driver names and objects //it is stored in the settings variable "AddDriverListview" //as a comma-separated list: // string[]= {driver1,device1,driver2,device2,..} string drivers = AgentSettings["AddDriverListview"]; if (drivers.IndexOf(",") != -1) { //values were stored as comma-separated list string[] items = drivers.Split(new char[] { ',' }); //get DRIVER_CHECK_INFO structs from the driver/device pairs ArrayList driversToCheck = DriverHelper.GetDriverInfoStructs(items); //bail completely if (driversToCheck == null) { AgentHeuristicMatches.KernelModeMatches.DriverIrpHooksTable = new CwStructures.HOOKED_DISPATCH_FUNCTIONS_TABLE[0]; return false; } AgentScanLog.AppendLine("------------------------"); AgentScanLog.AppendLine(" IRP DETOURS "); AgentScanLog.AppendLine("------------------------"); AgentHeuristicMatches.KernelModeMatches.DriverIrpDetoursTable = new CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE[driversToCheck.Count]; int count = 0; //loop through all drivers/device name combinations supplied by user and check for IRP hooks foreach (CwStructures.DRIVER_CHECK_INFO thisDriver in (CwStructures.DRIVER_CHECK_INFO[])driversToCheck.ToArray(typeof(CwStructures.DRIVER_CHECK_INFO))) { CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE DriverDetoursTable = new CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE(); try { DriverDetoursTable = HeuristicsKernelModeHelper.GetDetouredDispatchFunctionsInDriver(thisDriver); } catch (Exception ex) { AgentScanLog.AppendLine("SCAN: Error checking for IRP hooks: " + ex.Message); } AgentHeuristicMatches.KernelModeMatches.DriverIrpDetoursTable[count] = DriverDetoursTable; count++; } } else { AgentHeuristicMatches.KernelModeMatches.DriverIrpDetoursTable = new CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE[0]; } } else { AgentHeuristicMatches.KernelModeMatches.DriverIrpDetoursTable = new CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE[0]; } #endregion return true; }
///////////////////////////////////////////////////// // // // GetHookedDispatchFunctionsInDriver() // // // ///////////////////////////////////////////////////// //Description: Attempts to detect any hooked dispatch functions in the // given driver by examining its IRP table. // //Returns: a HOOKED_DISPATCH_FUNCTIONS_TABLE structure ///////////////////////////////////////////////////// internal static CwStructures.HOOKED_DISPATCH_FUNCTIONS_TABLE GetHookedDispatchFunctionsInDriver(CwStructures.DRIVER_CHECK_INFO driverInfoStruct) { //----------------------------- // SEND COMMAND //----------------------------- //build the IOCTL to send to driver uint ioctl = Win32Helper.GetIOCTL(CwConstants.CW_DRIVER_IRP_HOOK_DETECTION, Win32Helper.METHOD_OUT_DIRECT); //build our buffers int InBufSize = Marshal.SizeOf(typeof(CwStructures.DRIVER_CHECK_INFO)); int OutBufSize = Marshal.SizeOf(typeof(CwStructures.HOOKED_DISPATCH_FUNCTIONS_TABLE)); IntPtr lpInBuf = Marshal.AllocHGlobal(InBufSize); try { Marshal.StructureToPtr(driverInfoStruct, lpInBuf, true); } catch (Exception ex) { throw new Exception("SendDriverCommand() failed: " + ex.Message); } IntPtr lpOutBuf = Marshal.AllocHGlobal(OutBufSize); int bytesReturned = 0; //send the IOCTL try { bytesReturned = DriverHelper.SendDriverCommand(ioctl, lpInBuf, InBufSize, ref lpOutBuf, OutBufSize); } catch (Exception ex) { Marshal.FreeHGlobal(lpInBuf); throw new Exception("SendDriverCommand() failed: " + ex.Message); } Marshal.FreeHGlobal(lpInBuf); if (bytesReturned == 0) throw new Exception("A 0-length buffer was returned from the driver."); //----------------------------- // PROCESS RESULTS //----------------------------- CwStructures.HOOKED_DISPATCH_FUNCTIONS_TABLE DriverHookTable = new CwStructures.HOOKED_DISPATCH_FUNCTIONS_TABLE(); //try to marshal the ptr try { DriverHookTable = (CwStructures.HOOKED_DISPATCH_FUNCTIONS_TABLE)Marshal.PtrToStructure(lpOutBuf, typeof(CwStructures.HOOKED_DISPATCH_FUNCTIONS_TABLE)); } catch (Exception ex) { throw new Exception("Failed to marshal lpOutBuf pointer to DriverHookTable structure: " + ex.Message); } Marshal.FreeHGlobal(lpOutBuf); AgentScanLog.AppendLine("SCAN: Detected " + DriverHookTable.NumHookedEntries + " IRP hooks."); //loop through hooks and print them out in our log for (int i = 0; i < DriverHookTable.NumHookedEntries; i++) { CwStructures.HOOKED_DISPATCH_FUNCTION_ENTRY de = new CwStructures.HOOKED_DISPATCH_FUNCTION_ENTRY(); de = DriverHookTable.HookedEntries[i]; AgentScanLog.AppendLine("SCAN: " + de.DispatchFunctionName + "()'s major function code 0x"+de.IrpMajorFunctionHooked.ToString("x")+" is hooked to function at address 0x" + de.DispatchFunctionAddress.ToString("x")); } return DriverHookTable; }