import depuis ancien GitHub

This commit is contained in:
David Wuibaille
2025-10-31 08:38:13 +01:00
parent 6f3aeedc93
commit 6a2f2de58e
745 changed files with 178444 additions and 0 deletions

View File

@@ -0,0 +1,385 @@
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Res_Comment=This program injects a mass storage driver previously captured by CaptureMsd
#AutoIt3Wrapper_Res_Description=InjectMsd
#AutoIt3Wrapper_Res_Fileversion=1.1
#AutoIt3Wrapper_Res_LegalCopyright=Copyright LANDesk Software
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#cs ----------------------------------------------------------------------------
InjectMsd Version 1.0.1 08 Dec 2008
AutoIt Version: 3.2.12.1
Author: Jan Buelens, Landesk Software
Script Function:
Inject a mass storage driver into a freshly restored image. Context: we are still running under WinPE. The target machine has just been restored
from an image. We are about to reboot the target into mini-setup. But before the target reboots, we need to inject the correct mass storage sriver into
it.
This script expects a path as a command line parameter. Within that path, there should be following:
-1- A .inf and a .sys file, to be copied to c:\Windows\inf and c:\Windows\System32\drivers respectively
-2- A subfolder called "windows", to be copied recursively to c:\windows. This subfolder contains any additional files to be injected, e.g. DLLs.
There is a redundancy here (the .sys and .inf could just as well be in this subfolder), but item -1- above is still believed to be convenient.
-3- One or more .reg files. These were probably exported from a working machine using the same mass storage driver. Typically, two .reg files
will be needed. One to describe the "service" under HKLM\CurrentControlSet\Services. A second one to describe the driver's subkey under
HKLM\CurrentControlSet\Control\CriticalDeviceDatabase.
The script imports these .reg files into the target system's registry.
The path passed as a command line parameter must have write access because -1- the program will make a temp copy of the .reg files it finds, -2- the
program will create a log file called injectmsd.log.
If something goes wrong, the script returns a non-zero exit code. There will also be a message box that goes away after 10 seconds.
Change history:
V1.0.1 (08 Dec 08). In addition to HKLM\Software and HKLM\System, a .reg file can now also write to the target's HKEY_USERS\.Default.
v1.1 (07 July 09). The msd folder is no longer required as a command line parameter if a copydrivers.ini file (with a DriversTarget parameter in it)
is present in the folder from which this program is running. If copydrivers.ini has the "typical" DriversTarget path of c:\drivers, InjectMsd will
default to c:\drivers\msd. Non-existence of this folder will not be considered an error (exit code 0). If an msdfolder is specified on the command
line, however, it is required to exist.
The log file is in a different place than before (c:\drivers if that's what's in copydrivers.ini/DriversTarget).
#ce ----------------------------------------------------------------------------
#Include <File.au3>
$progname = "InjectMsd V1.1"
Dim $logfilename = "" ; log file (from /log command line parameter)
Dim $log = -1
Dim $MsdFolder = ""
; ===========================================================================================
; Validate command line parameters. There should be one command line parameter = base folder
; ===========================================================================================
For $n = 1 to $CmdLine[0]
$s = ""
$c = StringLeft($CmdLine[$n],1)
if $n = 1 And $c <> "/" And $c <> "-" Then
$MsdFolder = $CmdLine[1]
ElseIf ValParam($CmdLine[$n], "log", $s) Then
$logfilename = $s
Else
Usage()
EndIf
Next
LogOpen($logfilename)
if $MsdFolder = "" Then
; If no folder was specified on the command line, see if there is a copydrivers.ini with a DriversTarget parameter and default to msd subfolder off it.
; Example: if DriversTarget has its typical value of c:\drivers, default to c:\drivers\msd. If that folder does not exist, don't complain - this may be
; a normal case of a machine type that does not require an msd folder
$iniFilename = PathConcat(@ScriptDir, "copydrivers.ini") ; @ScriptDir is folder in which this script (or compiled program) resides
LogIniSection($iniFilename, "Config")
if FileExists($iniFilename) Then
$DriverPath = IniRead($iniFilename, "Config", "DriversTarget", "") ; normally c:\drivers
if $DriverPath <> "" Then
$MsdFolder = PathConcat($DriverPath, "msd")
if not IsFolder($MsdFolder) Then
LogMessage("Default msd folder (" & $MsdFolder & ") does not exist. No work to do - exiting")
Exit 0
EndIf
EndIf
EndIf
EndIf
if $MsdFolder = "" Then
; No msd folder was specified on the command line and we couldn't take a default from copydrivers.ini. Complain.
Usage()
EndIf
; If we defaulted the msdfolder based on DriversTarget in copydrivers.ini, we have already exited with a zero return code if the folder doesn't exist.
; But if an msdfolder was specified on the command line and it doesn't exist, we still complain.
if not IsFolder($MsdFolder) Then ErrorExit("Folder " & $MsdFolder & " does not exist.", 2)
; ===========================================================================================
; If there is a subfolder called windows, copy it to c:\Windows
; ===========================================================================================
CopyWindows() ; Copy Windows subfolder if any to C:\Windows
; ===========================================================================================
; Find .inf and .sys files and copy to C:\Windows\Inf and c:\windows\system32\drivers respectively. This
; is strictly speaking redundant since same can be achieved using CopyWindows. But is probably convenient.
; ===========================================================================================
$search = FileFindFirstFile(PathConcat($MsdFolder, "*.inf"))
While 1
$file = FileFindNextFile($search)
If @error Then ExitLoop
LogMessage("Copying " & $file & " to c:\windows\inf\")
FileCopy(PathConcat($MsdFolder, $file), "c:\windows\inf\", 1) ; 1 = overwrite
If @error Then LogMessage("Copy of " & $file & " failed")
WEnd
FileClose($search) ; Close the search handle
$search = FileFindFirstFile(PathConcat($MsdFolder, "*.sys"))
While 1
$file = FileFindNextFile($search)
If @error Then ExitLoop
LogMessage("Copying " & $file & " to c:\windows\system32\drivers\")
FileCopy(PathConcat($MsdFolder, $file), "c:\windows\system32\drivers\", 1) ; 1 = overwrite
If @error Then LogMessage("Copy of " & $file & " failed")
WEnd
FileClose($search) ; Close the search handle
; ===========================================================================================
; Find .reg files. For each .reg file, call ProcessReg.
; ===========================================================================================
$search = FileFindFirstFile(PathConcat($MsdFolder, "*.reg"))
While 1
$file = FileFindNextFile($search)
If @error Then ExitLoop
LogMessage("Processing " & $file)
ProcessReg(PathConcat($MsdFolder, $file))
WEnd
FileClose($search) ; Close the search handle
; ===========================================================================================
; Done
; ===========================================================================================
; ===========================================================================================
; If the folder that we got as a command line parameter has a subfolder called "windows", then xcopy it to C:\Windows
Func CopyWindows()
; ===========================================================================================
Local $SourceFolder = PathConcat($MsdFolder, "Windows")
Local $TargetFolder = "C:\Windows"
if Not IsFolder($SourceFolder) Then Return False
LogMessage("Copying " & $MsdFolder & "\Windows to c:\windows")
DirCreate($TargetFolder)
If Not IsFolder($TargetFolder) Then ErrorExit("Unable to create target folder: " & $TargetFolder, 6)
If Not DirCopy($SourceFolder, $TargetFolder, 1) Then ErrorExit("Unable to copy folder: " & $TargetFolder, 7) ; 1 means overwrite existing files
Return True
EndFunc
; ===========================================================================================
; Import a .reg file into the target's registry. Make a temp copy of the .reg file (called .reg1), with modified registry key names. We need to modify
; the registry key names because e.g. HKLM\System refers to the WinPE registry. We change HKLM\System to HKLM\System1 and HKLM\Software to HKLM\Software1.
; We also need to change CurrentControlSet to ControlSet001 because CurrentControlSet is an alias that only exists in the running system, not in the target's
; System hive on disk.
; We then use the REG LOAD command to mount the target system's HKLM\System registry hive as HKLM\System1 and HKLM\Software as HKLM\Software1. After that,
; we can use the REG IMPORT command to import the modified .reg file into the target's registry.
Func ProcessReg($file)
; ===========================================================================================
$tempfile = $file & "1"
LogMessage("Making temp copy of " & $file & ", the copy is called " & $tempfile)
FileCopy($file, $tempfile, 1) ; 1 = overwrite
if @error then ErrorExit("Unable to create " & $tempfile, 8)
if not FileExists($tempfile) then ErrorExit("Unable to create " & $tempfile, 9)
LogMessage("Editing " & $tempfile & ", replacing registry root key names")
$count1 = _ReplaceStringInFile($tempfile, "HKEY_LOCAL_MACHINE\System", "HKEY_LOCAL_MACHINE\System1")
$count2 = _ReplaceStringInFile($tempfile, "System1\CurrentControlSet", "System1\ControlSet001")
$count3 = _ReplaceStringInFile($tempfile, "HKEY_LOCAL_MACHINE\Software", "HKEY_LOCAL_MACHINE\Software1")
$count4 = _ReplaceStringInFile($tempfile, "HKEY_USERS\.DEFAULT", "HKEY_LOCAL_MACHINE\Default1")
if $count1 > 0 Then
if not FileExists("c:\windows\system32\config\system") Then ErrorExit("File not found: c:\windows\system32\config\system", 10)
RunCommand("reg load HKLM\System1 c:\windows\system32\config\system")
if not HasSubKey("HKLM\System1") Then ErrorExit("Something went wrong loading target's HKLM\System", 11)
EndIf
if $count3 > 0 Then
if not FileExists("c:\windows\system32\config\software") Then ErrorExit("File not found: c:\windows\system32\config\software", 12)
RunCommand("reg load HKLM\Software1 c:\windows\system32\config\software")
if not HasSubKey("HKLM\Software1") Then ErrorExit("Something went wrong loading target's HKLM\Software", 13)
EndIf
if $count4 > 0 Then
if not FileExists("c:\windows\system32\config\default") Then ErrorExit("File not found: c:\windows\system32\config\default", 12)
RunCommand("reg load HKLM\Default1 c:\windows\system32\config\default")
if not HasSubKey("HKLM\Default1") Then ErrorExit("Something went wrong loading target's HKEY_USERS\.DEFAULT", 13)
EndIf
RunCommand("reg import " & $tempfile)
if $count1 > 0 Then RunCommand("reg unload HKLM\System1")
if $count3 > 0 Then RunCommand("reg unload HKLM\Software1")
if $count4 > 0 Then RunCommand("reg unload HKLM\Default1")
EndFunc
; ===========================================================================================
; Return true if $s has a registry subkey
Func HasSubKey($s)
; ===========================================================================================
SetError(0)
Dim $subkey = ""
$subkey = RegEnumKey($s, 1)
if @error Then Return False
If $subkey = "" Then Return False
Return True
EndFunc
; ===========================================================================================
; Run specified command and include stdout and stderr output in our log file
Func RunCommand($cmd)
; ===========================================================================================
LogMessage("Running this command line: " & $cmd)
FileClose($log)
$command = "cmd /c " & $cmd & " >>" & $logfilename & " 2>&1"
RunWait($command)
$log = FileOpen($logfilename, 1) ; 1 = write, append mode
EndFunc
; ===========================================================================================
Func Usage()
; ===========================================================================================
Msgbox ("0", $progname, _
"This program injects a Mass Storage Driver previously captured with the" _
& @CRLF & "CaptureMsd program." & @CRLF _
& @CRLF & "Usage: InjectMsd [msdfolder] [parameters]" & @CRLF _
& @CRLF & "Msdfolder is the path where the driver files captured by CaptureMsd" _
& @CRLF & "are stored (typically a .sys, .inf and .reg). The msdfolder parameter" _
& @CRLF & "is optional if a copydrivers.ini file with appropriate parameters is" _
& @CRLF & "present in the folder from which InjectMsd is running." & @CRLF _
& @CRLF & "Parameters:" _
& @CRLF & "/log=<logfile> : log file" _
)
Exit 1
EndFunc
; ===========================================================================================
; Concatenate a filename ($s) with a base path
Func PathConcat($base, $s)
; ===========================================================================================
$base = StringStripWS($base,3)
$s = StringStripWS($s,3)
if StringRight($base,1) <> "\" Then $base &= "\"
if StringLeft($s,1) = "\" Then $s = StringTrimLeft($s,1)
Return $base & $s
EndFunc
; ===========================================================================================
; Return true if $s is a folder
Func IsFolder($s)
; ===========================================================================================
If Not FileExists($s) Or Not StringInStr(FileGetAttrib($s), "D") Then Return False
Return True
EndFunc
; ===========================================================================================
; Return true if $s is a network path. Must be full path.
Func IsRemote($s)
; ===========================================================================================
If StringLeft($s, 2) = "\\" Then Return True
Local $drive = StringLeft($s, 3)
if DriveGetType($drive) = "Network" Then Return True
Return False
EndFunc
; ===========================================================================================
Func LogCmdLine()
; ===========================================================================================
Local $n
LogMessage($progname & ", command line parameter(s): " & $CmdLine[0])
For $n = 1 to $CmdLine[0]
LogMessage(" " & $CmdLine[$n])
Next
EndFunc
; ===========================================================================================
Func LogMessage($msg)
; ===========================================================================================
FileWriteLine($log, $msg)
EndFunc
; ===========================================================================================
Func LogIniSection($inifilename, $inisection, $msg = Default)
; ===========================================================================================
Local $i
if $msg = Default Then
LogMessage($inifilename & ",section [" & $inisection & "]:")
Else
LogMessage($msg)
EndIf
Local $section = IniReadSection($inifilename, $inisection)
if @error Then
if not FileExists($inifilename) Then
LogMessage(" File does not exist: " & $inifilename)
Return
EndIf
LogMessage(" " & $inifilename & " includes no [" & $inisection & "] section")
Return
EndIf
For $i = 1 to $section[0][0]
LogMessage(" " & $section[$i][0] & " = " & $section[$i][1])
Next
EndFunc
; ===========================================================================================
Func LogOpen(ByRef $logfilename)
; ===========================================================================================
Local $scriptName = StringTrimRight(@ScriptName, 4)
While 1
If $logfilename <> "" Then
; log filename specified on command line
$log = FileOpen($logfilename, 10) ; 10 = 2 (write, create) + 8 (create path)
ExitLoop
EndIf
; No /log command line parameter. If there is a copydrivers.ini file with a DriversTarget parameter (typically c:\drivers), create the log in there
Local $iniFilename = PathConcat(@ScriptDir, "copydrivers.ini")
Local $DriverPath = IniRead($iniFilename, "Config", "DriversTarget", "")
if $DriverPath <> "" Then
$DriverPath = StringStripWS($DriverPath, 3)
if StringRight($DriverPath, 1) <> "\" Then $DriverPath &= "\"
$logfilename = $DriverPath & $scriptName & ".log"
$log = FileOpen($logfilename, 10) ; 10 = 2 (write, create) + 8 (create path)
if $log <> -1 Then ExitLoop
EndIf
; No /log command parameter and no copydrivers.ini. If running from a local path, create log in folder of running program
If Not IsRemote(@ScriptFullPath) Then
$logfilename = StringTrimRight(@ScriptFullPath, 3) & "log"
$log = FileOpen($logfilename, 2)
if $log <> -1 Then ExitLoop
EndIf
; failed to create log
$log = -1
$logfilename = ""
return
Wend
LogCmdLine()
EndFunc
; ===========================================================================================
Func ErrorExit($msg, $exitcode)
; ===========================================================================================
LogMessage($msg)
FileClose($log)
MsgBox(0x40010, $progname, $msg, 10) ; 10 is timeout, i.e. the msgbox closes after 10 seconds
Exit $exitcode
EndFunc
; ===========================================================================================
; parse command line parameter such as /keyw=something. Examples:
; ValParam("/path=c:\temp", "path", $value) sets $value to "c:\temp" and returns True
; ValParam("-path=c:\temp", "path", $value) sets $value to "c:\temp" and returns True
; ValParam("/path=c:\temp", "dir", $value) sets $value to "" and returns False
Func ValParam($param, $keyword, ByRef $value)
; ===========================================================================================
$value = ""
Local $p1 = "/" & $keyword & "="
Local $p2 = "-" & $keyword & "="
Local $len = StringLen($p1)
if StringLen($param) < ($len + 1) Then Return False
Local $t = StringLeft($param, $len)
if ($t <> $p1) And ($t <> $p2) Then Return False
$value = StringMid($param, $len + 1) ; 1 based
Return True
EndFunc