///////////////////////////////////////////////////// // // // GetDetouredDispatchFunctionsInDriver() // // // ///////////////////////////////////////////////////// //Description: Attempts to detect any detoured dispatch functions in the // given driver by examining those funcs' prologues. // //Returns: a DETOURED_DISPATCH_FUNCTIONS_TABLE structure ///////////////////////////////////////////////////// internal static CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE GetDetouredDispatchFunctionsInDriver(CwStructures.DRIVER_CHECK_INFO driverInfoStruct) { //----------------------------- // SEND COMMAND //----------------------------- //build the IOCTL to send to driver uint ioctl = Win32Helper.GetIOCTL(CwConstants.CW_DRIVER_IRP_DETOUR_DETECTION, Win32Helper.METHOD_OUT_DIRECT); //build our buffers int InBufSize = Marshal.SizeOf(typeof(CwStructures.DRIVER_CHECK_INFO)); int OutBufSize = Marshal.SizeOf(typeof(CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE)); IntPtr lpInBuf = Marshal.AllocHGlobal(InBufSize); Marshal.StructureToPtr(driverInfoStruct, lpInBuf, true); 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.DETOURED_DISPATCH_FUNCTIONS_TABLE DriverDetourTable = new CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE(); //try to marshal the ptr try { DriverDetourTable = (CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE)Marshal.PtrToStructure(lpOutBuf, typeof(CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE)); } catch (Exception ex) { throw new Exception("Failed to marshal lpOutBuf pointer to DriverDetourTable structure: " + ex.Message); } Marshal.FreeHGlobal(lpOutBuf); AgentScanLog.AppendLine("SCAN: Detected " + DriverDetourTable.NumDetours + " IRP detours."); //loop through hooks and print them out in our log for (int i = 0; i < DriverDetourTable.NumDetours; i++) { CwStructures.DETOURED_DISPATCH_FUNCTION_ENTRY de = new CwStructures.DETOURED_DISPATCH_FUNCTION_ENTRY(); de = DriverDetourTable.DetouredEntries[i]; AgentScanLog.AppendLine("SCAN: " + de.DispatchFunctionName + "()'s prologue is detoured to function at address 0x" + de.TargetAddress.ToString("x")); } return(DriverDetourTable); }
///////////////////////////////////////////////////// // // // GetDriverInfoStruct() // // // ///////////////////////////////////////////////////// //Description: Prepares a DRIVER_CHECK_INFO struct to // pass to CwDriver.sys. // //Throws: // //Returns: true if successful ///////////////////////////////////////////////////// internal unsafe static ArrayList GetDriverInfoStructs(string[] items) { ArrayList driversToCheck = new ArrayList(); //---------------------- //GET UNICODE STRINGS //---------------------- IntPtr hNtdll = Win32Helper.GetModuleHandle("ntdll.dll"); if (hNtdll == IntPtr.Zero) { AgentScanLog.AppendLine("GetDriverInfoStructs() failed to get handle to ntdll.dll: " + Win32Helper.GetLastError32()); return(null); } //1. find the address of RtlInitUnicodeString IntPtr RtlInitUnicodeString = IntPtr.Zero; try { RtlInitUnicodeString = Win32Helper.GetProcAddress(hNtdll, "RtlInitUnicodeString"); } catch (Exception ex) { Win32Helper.CloseHandle(hNtdll); AgentScanLog.AppendLine("GetDriverInfoStructs() failed to get address of RtlInitUnicodeString: " + ex.Message); return(null); } if (RtlInitUnicodeString == IntPtr.Zero) { Win32Helper.CloseHandle(hNtdll); AgentScanLog.AppendLine("GetDriverInfoStructs() returned a null address for RtlInitUnicodeString()."); return(null); } //2. marshal a delegate function from that pointer Win32Helper.RtlInitUnicodeStringDelegate _RtlInitUnicodeString; try { _RtlInitUnicodeString = (Win32Helper.RtlInitUnicodeStringDelegate)Marshal.GetDelegateForFunctionPointer(RtlInitUnicodeString, typeof(Win32Helper.RtlInitUnicodeStringDelegate)); } catch (Exception ex) { Win32Helper.CloseHandle(hNtdll); AgentScanLog.AppendLine("GetDriverInfoStructs() failed to retrieve delegate pointer: " + ex.Message); return(null); } //loop over drivers/devices to process for (int i = 0; i < items.Length / 2; i += 2) { CwStructures.DRIVER_CHECK_INFO aDriverToCheck = new CwStructures.DRIVER_CHECK_INFO(); //3. call RtlInitUnicodeString to fill our unicode strings with the driver's name and device name Win32Helper.UNICODE_STRING uDriverName = new Win32Helper.UNICODE_STRING(); Win32Helper.UNICODE_STRING uDeviceName = new Win32Helper.UNICODE_STRING(); _RtlInitUnicodeString(ref uDriverName, items[i]); _RtlInitUnicodeString(ref uDeviceName, items[i + 1]); //4. store the resulting pointer in our object aDriverToCheck.DriverName = uDriverName; aDriverToCheck.DriverDeviceName = uDeviceName; driversToCheck.Add(aDriverToCheck); } Win32Helper.CloseHandle(hNtdll); return(driversToCheck); }