|
| 1 | +function Get-Hash { |
| 2 | + [CmdletBinding()] |
| 3 | + param ( |
| 4 | + [Parameter( Position = 0, Mandatory = $True )] |
| 5 | + [string] |
| 6 | + $BaseInfo |
| 7 | + ) |
| 8 | + |
| 9 | + |
| 10 | + function local:Get-ShiftRight { |
| 11 | + [CmdletBinding()] |
| 12 | + param ( |
| 13 | + [Parameter( Position = 0, Mandatory = $true)] |
| 14 | + [long] $iValue, |
| 15 | + |
| 16 | + [Parameter( Position = 1, Mandatory = $true)] |
| 17 | + [int] $iCount |
| 18 | + ) |
| 19 | + |
| 20 | + if ($iValue -band 0x80000000) { |
| 21 | + Write-Output (( $iValue -shr $iCount) -bxor 0xFFFF0000) |
| 22 | + } |
| 23 | + else { |
| 24 | + Write-Output ($iValue -shr $iCount) |
| 25 | + } |
| 26 | + } |
| 27 | + |
| 28 | + |
| 29 | + function local:Get-Long { |
| 30 | + [CmdletBinding()] |
| 31 | + param ( |
| 32 | + [Parameter( Position = 0, Mandatory = $true)] |
| 33 | + [byte[]] $Bytes, |
| 34 | + |
| 35 | + [Parameter( Position = 1)] |
| 36 | + [int] $Index = 0 |
| 37 | + ) |
| 38 | + |
| 39 | + Write-Output ([BitConverter]::ToInt32($Bytes, $Index)) |
| 40 | + } |
| 41 | + |
| 42 | + function local:Convert-Int32 { |
| 43 | + param ( |
| 44 | + [Parameter( Position = 0, Mandatory = $true)] |
| 45 | + $Value |
| 46 | + ) |
| 47 | + |
| 48 | + [byte[]] $bytes = [BitConverter]::GetBytes($Value) |
| 49 | + return [BitConverter]::ToInt32( $bytes, 0) |
| 50 | + } |
| 51 | + |
| 52 | + [Byte[]] $bytesBaseInfo = [System.Text.Encoding]::Unicode.GetBytes($baseInfo) |
| 53 | + $bytesBaseInfo += 0x00, 0x00 |
| 54 | + |
| 55 | + $MD5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider |
| 56 | + [Byte[]] $bytesMD5 = $MD5.ComputeHash($bytesBaseInfo) |
| 57 | + |
| 58 | + $lengthBase = ($baseInfo.Length * 2) + 2 |
| 59 | + $length = (($lengthBase -band 4) -le 1) + (Get-ShiftRight $lengthBase 2) - 1 |
| 60 | + $base64Hash = "" |
| 61 | + |
| 62 | + if ($length -gt 1) { |
| 63 | + |
| 64 | + $map = @{PDATA = 0; CACHE = 0; COUNTER = 0 ; INDEX = 0; MD51 = 0; MD52 = 0; OUTHASH1 = 0; OUTHASH2 = 0; |
| 65 | + R0 = 0; R1 = @(0, 0); R2 = @(0, 0); R3 = 0; R4 = @(0, 0); R5 = @(0, 0); R6 = @(0, 0); R7 = @(0, 0) |
| 66 | + } |
| 67 | + |
| 68 | + $map.CACHE = 0 |
| 69 | + $map.OUTHASH1 = 0 |
| 70 | + $map.PDATA = 0 |
| 71 | + $map.MD51 = (((Get-Long $bytesMD5) -bor 1) + 0x69FB0000L) |
| 72 | + $map.MD52 = ((Get-Long $bytesMD5 4) -bor 1) + 0x13DB0000L |
| 73 | + $map.INDEX = Get-ShiftRight ($length - 2) 1 |
| 74 | + $map.COUNTER = $map.INDEX + 1 |
| 75 | + |
| 76 | + while ($map.COUNTER) { |
| 77 | + $map.R0 = Convert-Int32 ((Get-Long $bytesBaseInfo $map.PDATA) + [long]$map.OUTHASH1) |
| 78 | + $map.R1[0] = Convert-Int32 (Get-Long $bytesBaseInfo ($map.PDATA + 4)) |
| 79 | + $map.PDATA = $map.PDATA + 8 |
| 80 | + $map.R2[0] = Convert-Int32 (($map.R0 * ([long]$map.MD51)) - (0x10FA9605L * ((Get-ShiftRight $map.R0 16)))) |
| 81 | + $map.R2[1] = Convert-Int32 ((0x79F8A395L * ([long]$map.R2[0])) + (0x689B6B9FL * (Get-ShiftRight $map.R2[0] 16))) |
| 82 | + $map.R3 = Convert-Int32 ((0xEA970001L * $map.R2[1]) - (0x3C101569L * (Get-ShiftRight $map.R2[1] 16) )) |
| 83 | + $map.R4[0] = Convert-Int32 ($map.R3 + $map.R1[0]) |
| 84 | + $map.R5[0] = Convert-Int32 ($map.CACHE + $map.R3) |
| 85 | + $map.R6[0] = Convert-Int32 (($map.R4[0] * [long]$map.MD52) - (0x3CE8EC25L * (Get-ShiftRight $map.R4[0] 16))) |
| 86 | + $map.R6[1] = Convert-Int32 ((0x59C3AF2DL * $map.R6[0]) - (0x2232E0F1L * (Get-ShiftRight $map.R6[0] 16))) |
| 87 | + $map.OUTHASH1 = Convert-Int32 ((0x1EC90001L * $map.R6[1]) + (0x35BD1EC9L * (Get-ShiftRight $map.R6[1] 16))) |
| 88 | + $map.OUTHASH2 = Convert-Int32 ([long]$map.R5[0] + [long]$map.OUTHASH1) |
| 89 | + $map.CACHE = ([long]$map.OUTHASH2) |
| 90 | + $map.COUNTER = $map.COUNTER - 1 |
| 91 | + } |
| 92 | + |
| 93 | + [Byte[]] $outHash = @(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) |
| 94 | + [byte[]] $buffer = [BitConverter]::GetBytes($map.OUTHASH1) |
| 95 | + $buffer.CopyTo($outHash, 0) |
| 96 | + $buffer = [BitConverter]::GetBytes($map.OUTHASH2) |
| 97 | + $buffer.CopyTo($outHash, 4) |
| 98 | + |
| 99 | + $map = @{PDATA = 0; CACHE = 0; COUNTER = 0 ; INDEX = 0; MD51 = 0; MD52 = 0; OUTHASH1 = 0; OUTHASH2 = 0; |
| 100 | + R0 = 0; R1 = @(0, 0); R2 = @(0, 0); R3 = 0; R4 = @(0, 0); R5 = @(0, 0); R6 = @(0, 0); R7 = @(0, 0) |
| 101 | + } |
| 102 | + |
| 103 | + $map.CACHE = 0 |
| 104 | + $map.OUTHASH1 = 0 |
| 105 | + $map.PDATA = 0 |
| 106 | + $map.MD51 = ((Get-Long $bytesMD5) -bor 1) |
| 107 | + $map.MD52 = ((Get-Long $bytesMD5 4) -bor 1) |
| 108 | + $map.INDEX = Get-ShiftRight ($length - 2) 1 |
| 109 | + $map.COUNTER = $map.INDEX + 1 |
| 110 | + |
| 111 | + while ($map.COUNTER) { |
| 112 | + $map.R0 = Convert-Int32 ((Get-Long $bytesBaseInfo $map.PDATA) + ([long]$map.OUTHASH1)) |
| 113 | + $map.PDATA = $map.PDATA + 8 |
| 114 | + $map.R1[0] = Convert-Int32 ($map.R0 * [long]$map.MD51) |
| 115 | + $map.R1[1] = Convert-Int32 ((0xB1110000L * $map.R1[0]) - (0x30674EEFL * (Get-ShiftRight $map.R1[0] 16))) |
| 116 | + $map.R2[0] = Convert-Int32 ((0x5B9F0000L * $map.R1[1]) - (0x78F7A461L * (Get-ShiftRight $map.R1[1] 16))) |
| 117 | + $map.R2[1] = Convert-Int32 ((0x12CEB96DL * (Get-ShiftRight $map.R2[0] 16)) - (0x46930000L * $map.R2[0])) |
| 118 | + $map.R3 = Convert-Int32 ((0x1D830000L * $map.R2[1]) + (0x257E1D83L * (Get-ShiftRight $map.R2[1] 16))) |
| 119 | + $map.R4[0] = Convert-Int32 ([long]$map.MD52 * ([long]$map.R3 + (Get-Long $bytesBaseInfo ($map.PDATA - 4)))) |
| 120 | + $map.R4[1] = Convert-Int32 ((0x16F50000L * $map.R4[0]) - (0x5D8BE90BL * (Get-ShiftRight $map.R4[0] 16))) |
| 121 | + $map.R5[0] = Convert-Int32 ((0x96FF0000L * $map.R4[1]) - (0x2C7C6901L * (Get-ShiftRight $map.R4[1] 16))) |
| 122 | + $map.R5[1] = Convert-Int32 ((0x2B890000L * $map.R5[0]) + (0x7C932B89L * (Get-ShiftRight $map.R5[0] 16))) |
| 123 | + $map.OUTHASH1 = Convert-Int32 ((0x9F690000L * $map.R5[1]) - (0x405B6097L * (Get-ShiftRight ($map.R5[1]) 16))) |
| 124 | + $map.OUTHASH2 = Convert-Int32 ([long]$map.OUTHASH1 + $map.CACHE + $map.R3) |
| 125 | + $map.CACHE = ([long]$map.OUTHASH2) |
| 126 | + $map.COUNTER = $map.COUNTER - 1 |
| 127 | + } |
| 128 | + |
| 129 | + $buffer = [BitConverter]::GetBytes($map.OUTHASH1) |
| 130 | + $buffer.CopyTo($outHash, 8) |
| 131 | + $buffer = [BitConverter]::GetBytes($map.OUTHASH2) |
| 132 | + $buffer.CopyTo($outHash, 12) |
| 133 | + |
| 134 | + [Byte[]] $outHashBase = @(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) |
| 135 | + $hashValue1 = ((Get-Long $outHash 8) -bxor (Get-Long $outHash)) |
| 136 | + $hashValue2 = ((Get-Long $outHash 12) -bxor (Get-Long $outHash 4)) |
| 137 | + |
| 138 | + $buffer = [BitConverter]::GetBytes($hashValue1) |
| 139 | + $buffer.CopyTo($outHashBase, 0) |
| 140 | + $buffer = [BitConverter]::GetBytes($hashValue2) |
| 141 | + $buffer.CopyTo($outHashBase, 4) |
| 142 | + $base64Hash = [Convert]::ToBase64String($outHashBase) |
| 143 | + } |
| 144 | + |
| 145 | + Write-Output $base64Hash |
| 146 | + } |
| 147 | + |
| 148 | +function Get-Time { |
| 149 | + $now = [DateTime]::Now |
| 150 | + $dateTime = [DateTime]::New($now.Year, $now.Month, $now.Day, $now.Hour, $now.Minute, 0) |
| 151 | + $fileTime = $dateTime.ToFileTime() |
| 152 | + $hi = ($fileTime -shr 32) |
| 153 | + $low = ($fileTime -band 0xFFFFFFFFL) |
| 154 | + $dateTimeHex = ($hi.ToString("X8") + $low.ToString("X8")).ToLower() |
| 155 | + |
| 156 | + Write-Output $dateTimeHex |
| 157 | +} |
| 158 | + |
| 159 | +function Delete-UserChoiceKey { |
| 160 | + param ( |
| 161 | + [Parameter( Position = 0, Mandatory = $True )] |
| 162 | + [String] |
| 163 | + $Key |
| 164 | + ) |
| 165 | + $code = @' |
| 166 | + using System; |
| 167 | + using System.Runtime.InteropServices; |
| 168 | + using Microsoft.Win32; |
| 169 | +
|
| 170 | + namespace Registry { |
| 171 | + public class Utils { |
| 172 | + [DllImport("advapi32.dll", SetLastError = true)] |
| 173 | + private static extern int RegOpenKeyEx(UIntPtr hKey, string subKey, int ulOptions, int samDesired, out UIntPtr hkResult); |
| 174 | +
|
| 175 | + [DllImport("advapi32.dll", SetLastError=true, CharSet = CharSet.Unicode)] |
| 176 | + private static extern uint RegDeleteKey(UIntPtr hKey, string subKey); |
| 177 | +
|
| 178 | + public static void DeleteKey(string key) { |
| 179 | + UIntPtr hKey = UIntPtr.Zero; |
| 180 | + RegOpenKeyEx((UIntPtr)0x80000003u, key, 0, 0x20019, out hKey); |
| 181 | + RegDeleteKey((UIntPtr)0x80000003u, key); |
| 182 | + } |
| 183 | + } |
| 184 | + } |
| 185 | +'@ |
| 186 | + Add-Type -TypeDefinition $code |
| 187 | + |
| 188 | + [Registry.Utils]::DeleteKey($Key) |
| 189 | +} |
| 190 | + |
| 191 | +$Hive = $args[1] |
| 192 | + |
| 193 | +$userExperience = "" |
| 194 | +if ($Hive.StartsWith("S-")) |
| 195 | +{ |
| 196 | + $userExperienceSearch = "User Choice set via Windows User Experience" |
| 197 | + $user32Path = [Environment]::GetFolderPath([Environment+SpecialFolder]::SystemX86) + "\Shell32.dll" |
| 198 | + $fileStream = [System.IO.File]::Open($user32Path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite) |
| 199 | + $binaryReader = New-Object System.IO.BinaryReader($fileStream) |
| 200 | + [Byte[]] $bytesData = $binaryReader.ReadBytes(5mb) |
| 201 | + $fileStream.Close() |
| 202 | + $dataString = [Text.Encoding]::Unicode.GetString($bytesData) |
| 203 | + $position1 = $dataString.IndexOf($userExperienceSearch) |
| 204 | + $position2 = $dataString.IndexOf("}", $position1) |
| 205 | + |
| 206 | + $userExperience = $dataString.Substring($position1, $position2 - $position1 + 1) |
| 207 | +} |
| 208 | + |
| 209 | +Write-Host "Setting file associations for HKEY_USERS\$Hive..." |
| 210 | + |
| 211 | +New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS | Out-Null |
| 212 | + |
| 213 | +If (-NOT (Test-Path "HKU:\$Hive\SOFTWARE\Clients")) { |
| 214 | +New-Item -Path "HKU:\$Hive\SOFTWARE\Clients" -Force | Out-Null |
| 215 | +} |
| 216 | +If (-NOT (Test-Path "HKU:\$Hive\SOFTWARE\Clients\StartMenuInternet")) { |
| 217 | +New-Item -Path "HKU:\$Hive\SOFTWARE\Clients\StartMenuInternet" -Force | Out-Null |
| 218 | +} |
| 219 | + |
| 220 | +Get-Item -Path "HKLM:\SOFTWARE\Clients\StartMenuInternet\*" | |
| 221 | +ForEach-Object { |
| 222 | +Copy-Item -Path "$($_.PSPath)" -Destination "HKU:\$Hive\SOFTWARE\Clients\StartMenuInternet" -Force -Recurse | Out-Null |
| 223 | +} |
| 224 | + |
| 225 | +for ($i = 2; $i -lt $args.Length; $i++) { |
| 226 | + $splitArg = $args[$i] -split ":" |
| 227 | + if ($splitArg[0] -eq "Proto") { |
| 228 | + If (-NOT (Test-Path "HKU:\$Hive\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\$($splitArg[1])")) { |
| 229 | + New-Item -Path "HKU:\$Hive\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\$($splitArg[1])" -Force | Out-Null |
| 230 | + } |
| 231 | + If (Test-Path "HKU:\$Hive\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\$($splitArg[1])\UserChoice") { |
| 232 | + Delete-UserChoiceKey "$Hive\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\$($splitArg[1])\UserChoice" |
| 233 | + } |
| 234 | + If (-NOT (Test-Path "HKU:\$Hive\SOFTWARE\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts")) { |
| 235 | + New-Item -Path "HKU:\$Hive\SOFTWARE\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts" -Force | Out-Null |
| 236 | + } |
| 237 | + New-ItemProperty -Path "HKU:\$Hive\SOFTWARE\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts" -Name "$($splitArg[2])_$($splitArg[1])" -PropertyType DWORD -Value 0 -Force | Out-Null |
| 238 | + |
| 239 | + $dateTimeHex = Get-Time |
| 240 | + $hash = Get-Hash "$($splitArg[1])$Hive$($splitArg[2])$dateTimeHex$userExperience".ToLower() |
| 241 | + [Microsoft.Win32.Registry]::SetValue("HKEY_USERS\$Hive\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\$($splitArg[1])\UserChoice", "Hash", $hash) |
| 242 | + |
| 243 | + [Microsoft.Win32.Registry]::SetValue("HKEY_USERS\$Hive\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\$($splitArg[1])\UserChoice", "ProgId", "$($splitArg[2])") |
| 244 | + } else { |
| 245 | + If (-NOT (Test-Path "HKU:\$Hive\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$($splitArg[0])")) { |
| 246 | + New-Item -Path "HKU:\$Hive\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$($splitArg[0])" -Force | Out-Null |
| 247 | + } |
| 248 | + If (Test-Path "HKU:\$Hive\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$($splitArg[0])\UserChoice") { |
| 249 | + Delete-UserChoiceKey "$Hive\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$($splitArg[0])\UserChoice" |
| 250 | + } |
| 251 | + If (-NOT (Test-Path "HKU:\$Hive\SOFTWARE\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts")) { |
| 252 | + New-Item -Path "HKU:\$Hive\SOFTWARE\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts" -Force | Out-Null |
| 253 | + } |
| 254 | + New-ItemProperty -Path "HKU:\$Hive\SOFTWARE\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts" -Name "$($splitArg[1])_$($splitArg[0])" -PropertyType DWORD -Value 0 -Force | Out-Null |
| 255 | + |
| 256 | + if ($Hive.StartsWith("S-")) { |
| 257 | + $dateTimeHex = Get-Time |
| 258 | + $hash = Get-Hash "$($splitArg[0])$Hive$($splitArg[1])$dateTimeHex$userExperience".ToLower() |
| 259 | + |
| 260 | + [Microsoft.Win32.Registry]::SetValue("HKEY_USERS\$Hive\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$($splitArg[0])\UserChoice", "Hash", $hash) |
| 261 | + [Microsoft.Win32.Registry]::SetValue("HKEY_USERS\$Hive\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$($splitArg[0])\UserChoice", "ProgId", "$($splitArg[1])") |
| 262 | + } |
| 263 | + |
| 264 | + [Microsoft.Win32.Registry]::SetValue("HKEY_CLASSES_ROOT\$($splitArg[0])", "", "$($splitArg[1])") |
| 265 | + [Microsoft.Win32.Registry]::SetValue("HKEY_USERS\$Hive\SOFTWARE\Classes\$($splitArg[0])", "", "$($splitArg[1])") |
| 266 | + } |
| 267 | +} |
0 commit comments