Skip to content
61 changes: 61 additions & 0 deletions lib/core.ps1
Original file line number Diff line number Diff line change
@@ -1,3 +1,57 @@
# Returns the subsystem of the EXE
function Get-Subsystem($filePath) {
try {
$fileStream = [System.IO.FileStream]::new($filePath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite)
Comment thread
rashil2000 marked this conversation as resolved.
Outdated
$binaryReader = [System.IO.BinaryReader]::new($fileStream)
$binaryWriter = [System.IO.BinaryWriter]::new($fileStream)
} catch {
return -1 # leave the subsystem part silently
}

try {
$fileStream.Seek(0x3C, [System.IO.SeekOrigin]::Begin) | Out-Null
$peOffset = $binaryReader.ReadInt32()

$fileStream.Seek($peOffset, [System.IO.SeekOrigin]::Begin) | Out-Null
$fileHeaderOffset = $fileStream.Position

$fileStream.Seek(18, [System.IO.SeekOrigin]::Current) | Out-Null
$fileStream.Seek($fileHeaderOffset + 0x5C, [System.IO.SeekOrigin]::Begin) | Out-Null

return $binaryReader.ReadInt16()
} finally {
$binaryReader.Close()
$fileStream.Close()
}
}

function Change-Subsystem($filePath, $targetSubsystem) {
try {
$fileStream = [System.IO.FileStream]::new($filePath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite)
$binaryReader = [System.IO.BinaryReader]::new($fileStream)
$binaryWriter = [System.IO.BinaryWriter]::new($fileStream)
} catch {
Write-Output "Error opening File:'$filePath'"
return
}

try {
$fileStream.Seek(0x3C, [System.IO.SeekOrigin]::Begin) | Out-Null
$peOffset = $binaryReader.ReadInt32()

$fileStream.Seek($peOffset, [System.IO.SeekOrigin]::Begin) | Out-Null
$fileHeaderOffset = $fileStream.Position

$fileStream.Seek(18, [System.IO.SeekOrigin]::Current) | Out-Null
$fileStream.Seek($fileHeaderOffset + 0x5C, [System.IO.SeekOrigin]::Begin) | Out-Null

$binaryWriter.Write([System.Int16] $targetSubsystem)
} finally {
$binaryReader.Close()
$fileStream.Close()
}
}

function Optimize-SecurityProtocol {
# .NET Framework 4.7+ has a default security protocol called 'SystemDefault',
# which allows the operating system to choose the best protocol to use.
Expand Down Expand Up @@ -838,6 +892,13 @@ function shim($path, $global, $name, $arg) {
if ($arg) {
Write-Output "args = $arg" | Out-UTF8File "$shim.shim" -Append
}

$target_subsystem = Get-Subsystem $resolved_path

if (($target_subsystem -ne 3) -and ($target_subsystem -ge 0)) { # Subsystem -eq 3 means `Console`, -ge 0 to ignore
Write-Output "Changing Subsystem 3[current] to $target_subsystem[new] for $shim.exe"
Comment thread
rashil2000 marked this conversation as resolved.
Outdated
Change-Subsystem "$shim.exe" $target_subsystem
}
} elseif ($path -match '\.(bat|cmd)$') {
# shim .bat, .cmd so they can be used by programs with no awareness of PSH
warn_on_overwrite "$shim.cmd" $path
Expand Down