Skip to content

Instantly share code, notes, and snippets.

@mustelida
Last active November 15, 2022 19:26
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save mustelida/6e6325737780b316f802d9a2a89c8c92 to your computer and use it in GitHub Desktop.
Save mustelida/6e6325737780b316f802d9a2a89c8c92 to your computer and use it in GitHub Desktop.
Batch apply hex edits in PowerShell

Hexpatcher

Batch apply hex edits The edits to apply come from a CSV file in the same path

Usage

hexpatcher.ps1 has a short URL: https://git.io/vpNim

Start PowerShell 3.0+ and paste in:

'https://git.io/vpNim' | ? { icm { iwr $_ | iex } -arg $_ }

⚠️ This short URL always points to the latest revision. Read the code before you execute!

The script tries to find the program on PATH and prompts the user if it doesn't. You will get a log of the edits performed and the new SHA256 checksum.

Update

Sublime fucked up the build and the .exe file for builds 3200 onward still shows 3188. The latest entries are for 3207 but they say 3188 so it matches correctly.

#Requires -Version 2.0
# Batch apply hex edits
# The edits to apply come from a CSV file in the same path
# Reference: https://stackoverflow.com/questions/20935356/
# Handle HTTPS
[Net.ServicePointManager]::SecurityProtocol = 'Tls12, Tls11, Tls, Ssl3'
# More cock-smoking boilerplate
[System.Reflection.Assembly]::LoadWithPartialName('System.Web.Extensions')
# There is [Environment]::Is64BitProcess since PowerShell 3.0
function Get-Architecture {
param($FilePath)
[int32]$MACHINE_OFFSET = 4
[int32]$PE_POINTER_OFFSET = 60
[byte[]]$data = New-Object -TypeName System.Byte[] -ArgumentList 4096
$stream = New-Object -TypeName System.IO.FileStream -ArgumentList ($FilePath, 'Open', 'Read')
$stream.Read($data, 0, 4096) | Out-Null
[int32]$PE_HEADER_ADDR = [System.BitConverter]::ToInt32($data, $PE_POINTER_OFFSET)
[int32]$machineUint = [System.BitConverter]::ToUInt16($data, $PE_HEADER_ADDR + $MACHINE_OFFSET)
$result = ""
switch ($machineUint) {
0 { $result = "Native" }
0x014c { $result = "x86" }
0x0200 { $result = "Itanium" }
0x8664 { $result = "x64" }
}
$result
}
# TODO Add warning about executing code from the Internet
function Get-Data {
param (
[Parameter(Mandatory = $True)]
[String]
$pathstring
)
$abspath = ConvertTo-AbsoluteUri($pathstring)
$url = [System.Uri]::New($abspath)
$domain = $url.Host
If ($domain -match '^(github\.com|gist\.github|(cdn\.)?rawgit\.com)') {
$user = $url.Segments[1].Replace('/', '')
$id = $url.Segments[2].Replace('/', '')
$client = New-Object System.Net.WebClient
# Encourage your mom. It's fucking mandatory.
# Otherwise you get protocol violation error
$client.Headers.Add('Accept', 'application/vnd.github.v3+json')
# User-Agent also fucking mandatory. Suck cock, GitHub, gimme the fucking data
$client.Headers.Add('User-Agent', 'PowerShell')
$json = $client.DownloadString('https://api.github.com/gists/' + $id)
$ser = New-Object System.Web.Script.Serialization.JavaScriptSerializer
$obj = $ser.DeserializeObject($json)
# TODO WTF
$dataurl = $obj.files.Keys | Where-Object { $obj.files.Item($_).language -eq 'CSV' } | Select -First 1 | % { $obj.files.Item($_).raw_url }
Return $dataurl
} Else {
# TODO Prompt user
Return "sublime.csv"
}
}
# Take care of short URL redirection
function ConvertTo-AbsoluteUri {
param (
[String]
$pathstring
)
Return [System.Net.HttpWebRequest]::Create($pathstring).GetResponse().ResponseUri.AbsoluteUri
}
# Work in TEMP directory
Set-Location $env:TEMP
# Get URL from invocation and build CSV URL
# $RemotePath = Get-Data($_)
$RemotePath = Get-Data("sublime.csv") # DEBUG
# Store in user Temp folder with a random filename to avoid clashes
$LocalPath = $env:TEMP + '\' + [System.IO.Path]::GetRandomFileName()
# Request the file from the Gist
(New-Object System.Net.WebClient).DownloadFile($RemotePath, $LocalPath)
# Read the data from the CSV file
$entries = Import-Csv $LocalPath | Where-Object {$_.Platform -eq "Windows"}
# Get the program to work on
$target = $entries.Filename | Select-Object -First 1
# Try to find the target program on PATH
$program = Get-Command -ErrorAction SilentlyContinue $target | Get-Item
# If not ask user to input the path manually
while ($program -eq $null) {
$userinput = Read-Host "Enter path for executable to patch"
If (Test-Path $userinput -Include *.exe) {
$program = Get-Item -Path $userinput
} else {
Write-Error "Invalid file path, re-enter."
$program = $null
}
}
$name = $program.VersionInfo.ProductName
$build = $program.VersionInfo.ProductVersion
$arch = Get-Architecture $program
# Get the edits to apply for your build version and architecture
$edits = $entries | Where-Object {$_.Build -eq $build -and $_.Architecture -eq $arch}
If ($edits) {
# Kill if running
Start-Process -FilePath tskill -ArgumentList $program.BaseName `
-NoNewWindow -PassThru -Wait -RedirectStandardError nul | Out-Null
# Backup
try {
$program.CopyTo($([IO.Path]::ChangeExtension($program, '.bak')), $false) | Out-Null
} catch {
Write-Output $error[0].Exception.InnerException
} finally {
Write-Output "Original file backed up"
}
$bytes = [System.IO.File]::ReadAllBytes($program)
Write-Output "Patching $name build $build (Windows $arch)"
For ($i=0; $i -lt $edits.length; $i++) {
Write-Output "[$($i+1) of $($edits.length)] $($edits[$i].Offset) $($edits[$i].Original) > $($edits[$i].Modified)"
# Patch
$bytes[$edits[$i].Offset] = $edits[$i].Modified
# Will say it's in use by another program if not
Start-Sleep 2
}
# Write new bytes to file
# Will fail if you have it selected in Explorer! Just try again.
[System.IO.File]::WriteAllBytes($program, $bytes)
# Extra: Output new program hash
$hasher = [System.Security.Cryptography.HashAlgorithm]::Create('SHA256')
$hash = $hasher.ComputeHash([System.IO.File]::ReadAllBytes($program))
$hashString = [System.BitConverter]::ToString($hash).Replace('-', '')
Write-Output "Patched!" "New hash: $hashString"
} Else {
Write-Error "Could not locate patches."
}
Filename Build Platform Architecture Offset Original Modified
sublime_text.exe 3207 Windows x64 0x8545 0x84 0x85
sublime_text.exe 3207 Windows x64 0x193263 0x75 0x74
sublime_text.exe 3207 Windows x64 0x90315 0x48 0xC3
sublime_text.exe 3188 Windows x64 0x8545 0x84 0x85
sublime_text.exe 3188 Windows x64 0x193263 0x75 0x74
sublime_text.exe 3188 Windows x64 0x90315 0x48 0xC3
sublime_text 3200 Linux x64 0x3BEB98 0x84 0x85
sublime_text 3200 Linux x64 0x477C6E 0x75 0x74
sublime_text.exe 3200 Windows x64 0x8545 0x84 0x85
sublime_text.exe 3200 Windows x64 0x192487 0x75 0x74
sublime_text.exe 3200 Windows x64 0x8F6A8 0x48 0xC3
sublime_text.exe 3188 Windows x64 0x8545 0x84 0x85
sublime_text.exe 3188 Windows x64 0x192487 0x75 0x74
sublime_text.exe 3188 Windows x64 0x8F6A8 0x48 0xC3
sublime_text.exe 3193 Windows x64 0x58BA04 0x97 0x00
sublime_text.exe 3193 Windows x64 0x58BA05 0x94 0x00
sublime_text.exe 3193 Windows x64 0x58BA06 0x0D 0x00
sublime_text.exe 3190 Windows x64 0x583944 0x97 0x00
sublime_text.exe 3190 Windows x64 0x583945 0x94 0x00
sublime_text.exe 3190 Windows x64 0x583946 0x0D 0x00
sublime_text.exe 3176 Windows x64 0x76A0C 0x4C 0xEB
sublime_text.exe 3176 Windows x64 0x76A0D 0x8D 0x2A
sublime_text.exe 3176 Windows x64 0x76A2A 0x74 0x75
sublime_text.exe 3176 Windows x64 0xB27D9 0x84 0x85
sublime_text.exe 3176 Windows x64 0x23FF18 0x74 0x75
sublime_text 3176 Linux x64 0xD538 0x00 0x01
sublime_text.exe 3170 Windows x64 0x76608 0x4C 0xEB
sublime_text.exe 3170 Windows x64 0x23F89C 0x74 0x75
sublime_text.exe 3170 Windows x64 0x76626 0x74 0x75
sublime_text.exe 3170 Windows x64 0xB23C9 0x84 0x85
sublime_text.exe 3170 Windows x64 0x76609 0x8D 0x2A
sublime_text.exe 3143 Windows x64 0xB60F6 0x84 0x85
sublime_text.exe 3143 Windows x64 0x233F49 0x74 0x75
sublime_text.exe 3143 Windows x64 0x7691A 0x74 0x75
sublime_text.exe 3143 Windows x64 0x768FC 0x4C 0xEB
sublime_text.exe 3143 Windows x64 0x768FD 0x8D 0x2A
sublime_text.exe 3126 Windows x86 0xBA11D 0x1A 0x2A
sublime_text.exe 3126 Windows x64 0xFC53B 0x94 0x95
sublime_text.exe 3124 Windows x86 0xBA148 0x1A 0x2A
sublime_text.exe 3124 Windows x64 0xFC53B 0x94 0x95
sublime_text 3124* MacOSX x64 0x5D5D 0xF8 0xE0
sublime_text 3124 MacOSX x64 0x5DB0 0xF8 0xE0
sublime_text 3124 Linux x86 0xC34C 0x94 0x95
sublime_text 3124* Linux x64 0xC61E 0x94 0x95
sublime_text 3124 Linux x64 0xC668 0x94 0x95
sublime_text.exe 3122* Windows x86 0xB9F84 0x1A 0xFE
sublime_text.exe 3122 Windows x86 0xB9F84 0x1A 0x2A
sublime_text.exe 3122* Windows x64 0xFC458 0xF8 0xE0
sublime_text.exe 3122 Windows x64 0xFC45B 0x94 0x95
sublime_text 3122 MacOSX x64 0x5C29 0xF8 0xE0
sublime_text 3122 Linux x86 0xC34C 0x94 0x95
sublime_text 3122 Linux x64 0xC61E 0x94 0x95
sublime_text 3119 MacOSX x64 0x5B09 0xF8 0xE0
sublime_text.exe 3114* Windows x86 0xA22FB 0x1A 0xFE
sublime_text.exe 3114 Windows x86 0xA22FB 0x1A 0x2A
sublime_text.exe 3114** Windows x64 0xE795B 0xF8 0xE0
sublime_text.exe 3114* Windows x64 0xE62B1 0xF8 0xE0
sublime_text.exe 3114 Windows x64 0xE62B4 0x94 0x95
sublime_text 3114 MacOSX x64 0x5D9E 0xF8 0xE0
sublime_text 3114 Linux x86 0xC429 0x94 0x95
sublime_text 3114 Linux x64 0xC700 0x94 0x95
sublime_text.exe 3103 Windows x64 0xE61FD 0xF8 0xE0
Filename Build Platform Architecture Offset Original Modified
sublime_text.exe 3211 Windows x64 0x8545 0x84 0x85
sublime_text.exe 3211 Windows x64 0x08FF19 0x75 0xEB
sublime_text.exe 3211 Windows x64 0x1932C7 0x75 0x74
sublime_text.exe 3188 Windows x64 0x8545 0x84 0x85
sublime_text.exe 3188 Windows x64 0x193263 0x75 0x74
sublime_text.exe 3188 Windows x64 0x90315 0x48 0xC3
@fredgolightly
Copy link

3190?

@cipherknight
Copy link

sublime_text,3200,Linux,x64,0x3BEB98,0x84,0x85
sublime_text,3200,Linux,x64,0x477C6E,0x75,0x74

@mustelida
Copy link
Author

Build 3200 Windows x64 via this comment by @XcameronX

Copy link

ghost commented Mar 26, 2019

Cracking guide for Sublime Text 3 and Sublime Merge (Linux x86_64)

Sublime Text 3 - Build 3202 - Linux x64

Sources:

User URL
cipherhater https://gist.github.com/cipherhater/4e75d4e4551db171de03e9618456a7ea

st

Sublime Merge - Build 1111 - Linux x64

Sources:

User URL
cipherhater https://gist.github.com/cipherhater/4e75d4e4551db171de03e9618456a7ea

sm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment