Skip to content

Instantly share code, notes, and snippets.

@secdev02
Last active December 16, 2025 23:37
Show Gist options
  • Select an option

  • Save secdev02/c5cef7a9630313ee116494c9d68210ce to your computer and use it in GitHub Desktop.

Select an option

Save secdev02/c5cef7a9630313ee116494c9d68210ce to your computer and use it in GitHub Desktop.
Extractor
<#
.SYNOPSIS
Extracts a specific file from nested CAB files within an MSU package.
.DESCRIPTION
Extracts MSU to get CAB files, then extracts a specific file by name,
and performs additional expansion rounds if the file is itself a CAB.
.PARAMETER MsuPath
Path to the MSU file.
.PARAMETER TargetFileName
Name of the specific file to extract (e.g., "Windows10.0-KB5001234.cab").
.PARAMETER OutputPath
Directory where files will be extracted.
.EXAMPLE
.\Expand-MsuFile.ps1 -MsuPath "KB5001234.msu" -TargetFileName "Windows10.0-KB5001234.cab"
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$MsuPath,
[Parameter(Mandatory=$true)]
[string]$TargetFileName,
[Parameter(Mandatory=$false)]
[string]$OutputPath
)
# Check if MSU file exists
if (-not (Test-Path $MsuPath)) {
Write-Error "MSU file not found: $MsuPath"
exit 1
}
# Get absolute path
$MsuPath = (Resolve-Path $MsuPath).Path
$msuFileName = [System.IO.Path]::GetFileNameWithoutExtension($MsuPath)
# Set output path if not specified
if ([string]::IsNullOrEmpty($OutputPath)) {
$msuDirectory = [System.IO.Path]::GetDirectoryName($MsuPath)
$OutputPath = Join-Path $msuDirectory ($msuFileName + "_extracted")
}
# Create output directory
if (-not (Test-Path $OutputPath)) {
New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null
}
# Create temp directory
$tempPath = Join-Path $env:TEMP ("msu_temp_" + [System.Guid]::NewGuid().ToString())
New-Item -ItemType Directory -Path $tempPath -Force | Out-Null
Write-Host "Step 1: Extracting MSU..." -ForegroundColor Cyan
Write-Host "Source: $MsuPath" -ForegroundColor Gray
# Extract MSU
$expandArgs = "-F:* `"$MsuPath`" `"$tempPath`""
$result = Start-Process -FilePath "expand.exe" -ArgumentList $expandArgs -Wait -PassThru -NoNewWindow
if ($result.ExitCode -ne 0) {
Write-Error "Failed to extract MSU (exit code: $($result.ExitCode))"
Remove-Item -Path $tempPath -Recurse -Force
exit 1
}
Write-Host "MSU extracted" -ForegroundColor Green
# Step 2: Find the target file
Write-Host "`nStep 2: Looking for '$TargetFileName'..." -ForegroundColor Cyan
$targetFile = Get-ChildItem -Path $tempPath -Filter $TargetFileName -Recurse -File | Select-Object -First 1
if ($null -eq $targetFile) {
Write-Error "Target file '$TargetFileName' not found in MSU"
Write-Host "`nAvailable files:" -ForegroundColor Yellow
Get-ChildItem -Path $tempPath -Recurse -File | ForEach-Object { Write-Host " $($_.Name)" }
Remove-Item -Path $tempPath -Recurse -Force
exit 1
}
Write-Host "Found: $($targetFile.FullName)" -ForegroundColor Green
# Step 3: Extract the target file (first CAB)
$temp2Path = Join-Path $tempPath "extract1"
New-Item -ItemType Directory -Path $temp2Path -Force | Out-Null
Write-Host "`nStep 3: Extracting first layer..." -ForegroundColor Cyan
$expandArgs = "-F:* `"$($targetFile.FullName)`" `"$temp2Path`""
$result = Start-Process -FilePath "expand.exe" -ArgumentList $expandArgs -Wait -PassThru -NoNewWindow
if ($result.ExitCode -ne 0) {
Write-Warning "First extraction returned exit code: $($result.ExitCode)"
}
$extractedFiles = Get-ChildItem -Path $temp2Path -File
Write-Host "Extracted $($extractedFiles.Count) file(s)" -ForegroundColor Green
# Step 4: Check for nested CAB and extract again
Write-Host "`nStep 4: Looking for nested CAB..." -ForegroundColor Cyan
$nestedCab = Get-ChildItem -Path $temp2Path -Filter "*.cab" -File | Select-Object -First 1
if ($null -ne $nestedCab) {
Write-Host "Found nested CAB: $($nestedCab.Name)" -ForegroundColor Yellow
Write-Host "Performing second expansion..." -ForegroundColor Cyan
$expandArgs = "-F:* `"$($nestedCab.FullName)`" `"$OutputPath`""
$result = Start-Process -FilePath "expand.exe" -ArgumentList $expandArgs -Wait -PassThru -NoNewWindow
if ($result.ExitCode -eq 0) {
Write-Host "Final extraction complete!" -ForegroundColor Green
} else {
Write-Warning "Second extraction returned exit code: $($result.ExitCode)"
}
} else {
Write-Host "No nested CAB found, copying files to output..." -ForegroundColor Yellow
Copy-Item -Path (Join-Path $temp2Path "*") -Destination $OutputPath -Recurse -Force
}
# Clean up temp directory
Write-Host "`nCleaning up..." -ForegroundColor Cyan
Remove-Item -Path $tempPath -Recurse -Force
Write-Host "`n==================================" -ForegroundColor Green
Write-Host "Extraction complete!" -ForegroundColor Green
Write-Host "Output: $OutputPath" -ForegroundColor Green
Write-Host "==================================" -ForegroundColor Green
# Show extracted files
$finalFiles = Get-ChildItem -Path $OutputPath -File -Recurse
Write-Host "`nExtracted $($finalFiles.Count) file(s):" -ForegroundColor Cyan
$finalFiles | Select-Object -First 20 | ForEach-Object { Write-Host " $($_.Name)" -ForegroundColor Gray }
if ($finalFiles.Count -gt 20) {
Write-Host " ... and $($finalFiles.Count - 20) more" -ForegroundColor Gray
}
<#
.SYNOPSIS
Applies a delta patch to reconstruct the complete PE file
.DESCRIPTION
Takes a delta patch file and the original system file, then applies the patch
to create the complete updated PE file. Supports PA30, PA19, DCN1, DCM1 formats.
.PARAMETER DeltaFile
Path to the delta patch file
.PARAMETER SourceFile
Path to the original system file (if not provided, will auto-search)
.PARAMETER OutputFile
Path where the complete PE will be saved
.EXAMPLE
.\Apply-DeltaPatch.ps1 -DeltaFile "prjflt.sys"
.EXAMPLE
.\Apply-DeltaPatch.ps1 -DeltaFile "prjflt.sys" -SourceFile "C:\Windows\System32\drivers\prjflt.sys" -OutputFile "prjflt_new.sys"
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$DeltaFile,
[Parameter(Mandatory=$false)]
[string]$SourceFile,
[Parameter(Mandatory=$false)]
[string]$OutputFile
)
function Get-DeltaInfo {
param([string]$FilePath)
$bytes = New-Object byte[] 16
$stream = [System.IO.File]::OpenRead($FilePath)
$stream.Read($bytes, 0, 16) | Out-Null
$stream.Close()
$signature = [System.Text.Encoding]::ASCII.GetString($bytes[0..3])
return @{
Signature = $signature
IsPA30 = ($signature -eq "PA30")
IsPA19 = ($signature -eq "PA19")
IsDCN1 = ($signature -eq "DCN1")
IsDCM1 = ($signature -eq "DCM1")
IsDelta = ($signature -eq "PA30" -or $signature -eq "PA19" -or $signature -eq "DCN1" -or $signature -eq "DCM1")
}
}
function Find-SystemFile {
param([string]$FileName)
Write-Host " Searching for: $FileName" -ForegroundColor Gray
$searchPaths = @(
"$env:SystemRoot\System32\drivers",
"$env:SystemRoot\System32",
"$env:SystemRoot\SysWOW64",
"$env:SystemRoot\WinSxS"
)
foreach ($path in $searchPaths) {
if (Test-Path $path) {
Write-Host " Checking: $path" -ForegroundColor DarkGray
$found = Get-ChildItem -Path $path -Filter $FileName -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1
if ($found) {
Write-Host " Found!" -ForegroundColor Green
return $found.FullName
}
}
}
return $null
}
function Invoke-DeltaAPI {
param(
[string]$SourcePath,
[string]$DeltaPath,
[string]$TargetPath
)
Write-Host "`n[Method 1] Windows Delta API (msdelta.dll)" -ForegroundColor Cyan
try {
# Load msdelta.dll
$signature = @'
[DllImport("msdelta.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool ApplyDeltaB(
long ApplyFlags,
string SourceName,
string DeltaName,
string TargetName);
[DllImport("msdelta.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool ApplyDeltaW(
long ApplyFlags,
string SourceName,
string DeltaName,
string TargetName);
'@
Add-Type -MemberDefinition $signature -Name DeltaPatcher -Namespace Win32 -ErrorAction Stop
Write-Host " Loaded msdelta.dll" -ForegroundColor Green
Write-Host " Applying delta patch..." -ForegroundColor Gray
# Try ApplyDeltaB first
$result = [Win32.DeltaPatcher]::ApplyDeltaB(0, $SourcePath, $DeltaPath, $TargetPath)
if ($result) {
Write-Host " SUCCESS! Delta applied with ApplyDeltaB" -ForegroundColor Green
return $true
}
# Try ApplyDeltaW
$result = [Win32.DeltaPatcher]::ApplyDeltaW(0, $SourcePath, $DeltaPath, $TargetPath)
if ($result) {
Write-Host " SUCCESS! Delta applied with ApplyDeltaW" -ForegroundColor Green
return $true
}
$errorCode = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
Write-Warning " Failed with error code: 0x$($errorCode.ToString('X8'))"
return $false
} catch {
Write-Warning " Could not use Delta API: $_"
return $false
}
}
function Invoke-ExpandDelta {
param(
[string]$SourcePath,
[string]$DeltaPath,
[string]$TargetPath
)
Write-Host "`n[Method 2] expand.exe with delta support" -ForegroundColor Cyan
try {
# Create temp directory
$tempDir = Join-Path $env:TEMP ("delta_expand_" + [System.Guid]::NewGuid().ToString().Substring(0,8))
New-Item -ItemType Directory -Path $tempDir -Force | Out-Null
# Copy files to temp
$tempSource = Join-Path $tempDir "source"
$tempDelta = Join-Path $tempDir "delta"
Copy-Item $SourcePath $tempSource -Force
Copy-Item $DeltaPath $tempDelta -Force
Write-Host " Running expand.exe..." -ForegroundColor Gray
# Try expand with -R flag (handles deltas)
$expandArgs = "-R `"$tempDelta`" -F:* `"$tempDir`""
$proc = Start-Process -FilePath "expand.exe" -ArgumentList $expandArgs -Wait -PassThru -NoNewWindow
# Check if output was created
$possibleOutputs = Get-ChildItem -Path $tempDir -File | Where-Object { $_.Name -ne "source" -and $_.Name -ne "delta" }
if ($possibleOutputs -and $possibleOutputs.Count -gt 0) {
Copy-Item $possibleOutputs[0].FullName $TargetPath -Force
Remove-Item $tempDir -Recurse -Force
Write-Host " SUCCESS! File expanded" -ForegroundColor Green
return $true
}
Remove-Item $tempDir -Recurse -Force
Write-Warning " expand.exe did not produce output"
return $false
} catch {
Write-Warning " expand.exe method failed: $_"
return $false
}
}
function Invoke-DeltaPatcherTool {
param(
[string]$SourcePath,
[string]$DeltaPath,
[string]$TargetPath
)
Write-Host "`n[Method 3] Looking for delta patcher tools..." -ForegroundColor Cyan
# Check for common delta tools
$tools = @(
@{Name="DeltaPatcher"; Path="deltapatcher.exe"; Args="`"$SourcePath`" `"$DeltaPath`" `"$TargetPath`""},
@{Name="pa30patch"; Path="pa30patch.exe"; Args="`"$SourcePath`" `"$DeltaPath`" `"$TargetPath`""}
)
foreach ($tool in $tools) {
$toolPath = (Get-Command $tool.Path -ErrorAction SilentlyContinue).Source
if ($toolPath) {
Write-Host " Found: $($tool.Name)" -ForegroundColor Green
Write-Host " Running..." -ForegroundColor Gray
$proc = Start-Process -FilePath $toolPath -ArgumentList $tool.Args -Wait -PassThru -NoNewWindow
if ($proc.ExitCode -eq 0 -and (Test-Path $TargetPath)) {
Write-Host " SUCCESS!" -ForegroundColor Green
return $true
}
}
}
Write-Host " No delta patcher tools found in PATH" -ForegroundColor Yellow
return $false
}
# Main script
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Delta Patch Decompression Tool" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
# Validate delta file
if (-not (Test-Path $DeltaFile)) {
Write-Error "Delta file not found: $DeltaFile"
exit 1
}
$DeltaFile = (Resolve-Path $DeltaFile).Path
$deltaFileName = [System.IO.Path]::GetFileName($DeltaFile)
$deltaSize = (Get-Item $DeltaFile).Length
Write-Host "`nDelta File: $deltaFileName" -ForegroundColor Yellow
Write-Host "Path: $DeltaFile" -ForegroundColor Gray
Write-Host "Size: $([math]::Round($deltaSize/1KB, 2)) KB" -ForegroundColor Gray
# Check delta type
$deltaInfo = Get-DeltaInfo -FilePath $DeltaFile
Write-Host "`nDelta Format: $($deltaInfo.Signature)" -ForegroundColor Yellow
if (-not $deltaInfo.IsDelta) {
Write-Error "This doesn't appear to be a delta patch file (signature: $($deltaInfo.Signature))"
exit 1
}
Write-Host " ✓ Confirmed delta patch" -ForegroundColor Green
# Find or validate source file
Write-Host "`n----------------------------------------" -ForegroundColor Cyan
Write-Host "Finding Original File" -ForegroundColor Cyan
Write-Host "----------------------------------------" -ForegroundColor Cyan
if ([string]::IsNullOrEmpty($SourceFile)) {
Write-Host " No source file specified, searching system..." -ForegroundColor Gray
$SourceFile = Find-SystemFile -FileName $deltaFileName
}
if (-not $SourceFile -or -not (Test-Path $SourceFile)) {
Write-Error "Cannot find original file: $deltaFileName"
Write-Host "`nYou need to specify the original file with -SourceFile parameter" -ForegroundColor Yellow
Write-Host "Example: -SourceFile `"C:\Windows\System32\drivers\$deltaFileName`"" -ForegroundColor Gray
exit 1
}
$SourceFile = (Resolve-Path $SourceFile).Path
$sourceSize = (Get-Item $SourceFile).Length
Write-Host "`nSource File Found:" -ForegroundColor Green
Write-Host " Path: $SourceFile" -ForegroundColor Gray
Write-Host " Size: $([math]::Round($sourceSize/1KB, 2)) KB" -ForegroundColor Gray
# Setup output file
if ([string]::IsNullOrEmpty($OutputFile)) {
$deltaDir = [System.IO.Path]::GetDirectoryName($DeltaFile)
$baseName = [System.IO.Path]::GetFileNameWithoutExtension($deltaFileName)
$ext = [System.IO.Path]::GetExtension($deltaFileName)
$OutputFile = Join-Path $deltaDir ($baseName + "_patched" + $ext)
}
Write-Host "`nOutput File:" -ForegroundColor Cyan
Write-Host " $OutputFile" -ForegroundColor Gray
# Try different methods
Write-Host "`n----------------------------------------" -ForegroundColor Cyan
Write-Host "Applying Delta Patch" -ForegroundColor Cyan
Write-Host "----------------------------------------" -ForegroundColor Cyan
$success = $false
# Method 1: Windows Delta API
$success = Invoke-DeltaAPI -SourcePath $SourceFile -DeltaPath $DeltaFile -TargetPath $OutputFile
# Method 2: expand.exe
if (-not $success) {
$success = Invoke-ExpandDelta -SourcePath $SourceFile -DeltaPath $DeltaFile -TargetPath $OutputFile
}
# Method 3: External tools
if (-not $success) {
$success = Invoke-DeltaPatcherTool -SourcePath $SourceFile -DeltaPath $DeltaFile -TargetPath $OutputFile
}
# Check result
Write-Host "`n========================================" -ForegroundColor Cyan
if ($success -and (Test-Path $OutputFile)) {
$outputSize = (Get-Item $OutputFile).Length
Write-Host "SUCCESS! Complete PE File Created!" -ForegroundColor Green
Write-Host "========================================" -ForegroundColor Green
Write-Host "`nOutput File: $OutputFile" -ForegroundColor Cyan
Write-Host "Size: $([math]::Round($outputSize/1KB, 2)) KB" -ForegroundColor Gray
# Verify it's a PE
$peBytes = New-Object byte[] 2
$stream = [System.IO.File]::OpenRead($OutputFile)
$stream.Read($peBytes, 0, 2) | Out-Null
$stream.Close()
if ($peBytes[0] -eq 0x4D -and $peBytes[1] -eq 0x5A) {
Write-Host "✓ Verified: Valid PE file (MZ header)" -ForegroundColor Green
# Show file info
try {
$versionInfo = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($OutputFile)
Write-Host "`nFile Information:" -ForegroundColor Cyan
Write-Host " Description: $($versionInfo.FileDescription)" -ForegroundColor Gray
Write-Host " Version: $($versionInfo.FileVersion)" -ForegroundColor Gray
Write-Host " Product: $($versionInfo.ProductName)" -ForegroundColor Gray
} catch {
Write-Host "`n(Could not read version info)" -ForegroundColor DarkGray
}
} else {
Write-Warning "File created but doesn't have PE signature"
}
Write-Host "`nYou can now analyze this file with:" -ForegroundColor Cyan
Write-Host " - PE-bear" -ForegroundColor Gray
Write-Host " - IDA Pro / Ghidra" -ForegroundColor Gray
Write-Host " - CFF Explorer" -ForegroundColor Gray
Write-Host " - dumpbin /headers `"$OutputFile`"" -ForegroundColor Gray
} else {
Write-Host "FAILED - Could Not Apply Delta Patch" -ForegroundColor Red
Write-Host "========================================" -ForegroundColor Red
Write-Host "`nPossible solutions:" -ForegroundColor Yellow
Write-Host " 1. Wrong source file version - make sure source matches the delta" -ForegroundColor Gray
Write-Host " 2. Try downloading delta tools:" -ForegroundColor Gray
Write-Host " - DeltaPatcher from GitHub" -ForegroundColor Gray
Write-Host " - pa30patch.exe" -ForegroundColor Gray
Write-Host " 3. Use DISM to extract:" -ForegroundColor Gray
Write-Host " dism /Online /Get-Packages" -ForegroundColor Gray
Write-Host " 4. Check Windows Update log for the correct base version" -ForegroundColor Gray
exit 1
}
Write-Host "`n========================================" -ForegroundColor Cyan
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment