Windows 11 AME playbook for AME Wizard.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

254 lines
11 KiB

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