///////////////////////////////////////////////////// // // // SysLoadAndCall() // // // ///////////////////////////////////////////////////// //Description: Loads driver binary into memory using // undocumented ZwSetSystemInformation(). // //Returns: Nothing ////////////////////////////////////////////////////// internal static unsafe void SysLoadAndCall(string fullpath, ref bool success) { string drvFullPath = "\\\\??\\\\" + fullpath.Replace("\\", "\\\\"); IntPtr pSystemLoadAndCallImage=IntPtr.Zero; Win32Helper.SYSTEM_LOAD_AND_CALL_IMAGE SystemLoadAndCallImage = new Win32Helper.SYSTEM_LOAD_AND_CALL_IMAGE(); Win32Helper.UNICODE_STRING UnicodeString = new Win32Helper.UNICODE_STRING(); //get pointers to the functions we need IntPtr RtlInitUnicodeString = Win32Helper.GetProcAddress(Win32Helper.GetModuleHandle("ntdll.dll"), "RtlInitUnicodeString"); IntPtr ZwSetSystemInformation = Win32Helper.GetProcAddress(Win32Helper.GetModuleHandle("ntdll.dll"), "ZwSetSystemInformation"); //marshal a delegate function from those pointers. if (RtlInitUnicodeString != IntPtr.Zero && ZwSetSystemInformation != IntPtr.Zero) { //get delegate func for RtlInitUnicodeString() Win32Helper.RtlInitUnicodeStringDelegate _RtlInitUnicodeString = (Win32Helper.RtlInitUnicodeStringDelegate)Marshal.GetDelegateForFunctionPointer(RtlInitUnicodeString, typeof(Win32Helper.RtlInitUnicodeStringDelegate)); //get delegate func for ZwSetSystemInformation() Win32Helper.ZwSetSystemInformationDelegate _ZwSetSystemInformation = (Win32Helper.ZwSetSystemInformationDelegate)Marshal.GetDelegateForFunctionPointer(ZwSetSystemInformation, typeof(Win32Helper.ZwSetSystemInformationDelegate)); //marshal a pointer to the unicode string field of the SystemLoadAndCall structure //Marshal.StructureToPtr(SystemLoadAndCallImage.ModuleName, pUnicodeString, false); //pass the pointer to the module name field of that structure to be initialized to the image path _RtlInitUnicodeString(ref UnicodeString, drvFullPath); SystemLoadAndCallImage.ModuleName = UnicodeString; //get a pointer to our now-initialised LoadAndCallImage Marshal.StructureToPtr(SystemLoadAndCallImage, pSystemLoadAndCallImage, false); //pass that structure to ZwSetSystemInformation..and .. bam.. if (_ZwSetSystemInformation(38, pSystemLoadAndCallImage, (uint)Marshal.SizeOf(SystemLoadAndCallImage))) success = true; } success = false; }
///////////////////////////////////////////////////// // // // GetDriverInfoStruct() // // // ///////////////////////////////////////////////////// //Description: Prepares a DRIVER_CHECK_INFO struct to // pass to CwDriver.sys. // //Throws: // //Returns: true if successful ///////////////////////////////////////////////////// internal static unsafe 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; }