mirror of
https://github.com/chylex/Blog.git
synced 2025-05-23 15:34:04 +02:00
Add post - Open Executables Without Saving In Firefox 57+
This commit is contained in:
parent
f544ac868d
commit
cc17ad3f40
_posts
assets
50
_posts/2020-03-25-firefox-open-exe.md
Normal file
50
_posts/2020-03-25-firefox-open-exe.md
Normal file
@ -0,0 +1,50 @@
|
||||
---
|
||||
title: "Open Executables Without Saving In Firefox 57+"
|
||||
subtitle: "%pub"
|
||||
date: 2020-03-25
|
||||
commentid: 3
|
||||
---
|
||||
|
||||
Since Firefox 57, extensions such as OpenDownload² can no longer modify the Download dialog, removing the option to run executables without manually saving them first. Here is a PowerShell script to fix that.
|
||||
|
||||
### Before
|
||||
|
||||

|
||||
|
||||
### After
|
||||
|
||||

|
||||
|
||||
# How to Use
|
||||
|
||||
1. [Download the script](/assets/download/firefox-open-exe/FirefoxOpenExePatch.ps1)
|
||||
2. Close Firefox
|
||||
3. Open PowerShell in the folder with the downloaded script
|
||||
- If you installed Firefox into a protected location (such as Program Files), you will need to run PowerShell as Administrator, and navigate to the script folder using `cd "<folder>"`
|
||||
- Otherwise, you can simply open the script folder in Windows Explorer and type `powershell` into the address bar
|
||||
4. Type `.\FirefoxOpenExePatch.ps1 "<firefox-folder>"` into PowerShell and press Enter
|
||||
- For ex.: `.\FirefoxOpenExePatch.ps1 "C:\Program Files\Mozilla Firefox"`
|
||||
5. After the patching completes, make sure it says `Applied 4 patches`
|
||||
- If it's fewer, it may still work but not 100%
|
||||
- If it's more, it probably touched something it shouldn't have
|
||||
6. Delete `compatibility.ini` from your Firefox profile folder to regenerate the download dialog
|
||||
- For non-portable installs, your profile is in `%APPDATA%\Mozilla\Firefox\Profiles\<profile-id>`
|
||||
- For portable installs, your profile is in `<installation-folder>\Data\profile`
|
||||
7. Repeat when Firefox updates
|
||||
|
||||
If you cannot run PowerShell scripts, follow [this guide](https://social.technet.microsoft.com/wiki/contents/articles/38496.unblock-downloaded-powershell-scripts.aspx).
|
||||
|
||||
If you see an error message, read it, most times you should be able to figure out what's wrong. If the patch succeeds but Firefox doesn't work, revert the patch by renaming `omni.ja.old` to `omni.ja`.
|
||||
|
||||
Please let me know in the comments if a Firefox update breaks the patch. If this guide works for you, I'd appreciate if you [bought me a coffee](https://ko-fi.com/chylex).
|
||||
|
||||
# How it Works
|
||||
|
||||
In the Firefox installation folder, `omni.ja` is a ZIP file with no compression. The archive contains `modules\HelperAppDlg.jsm` (or `components/nsHelperAppDlg.js` in older versions) with JavaScript logic for the download dialog.
|
||||
|
||||
The patch does 2 things:
|
||||
|
||||
1. It replaces `this.mLauncher.targetFileIsExecutable` with `false` in 3 places to make executables pretend they are normal files, so they will not trigger the "simple" download dialog.
|
||||
2. It modifies a condition that checks which option (`Open with` or `Save File`) is checked by default, to make executables default to `Open with`.
|
||||
|
||||
Because the ZIP file has no compression, the script treats it as a binary file and simply searches it for byte sequences to replace. The replacement bytes are written so that they don't affect the file size. Changing the ZIP file bytes *corrupts* it because the CRC checksum no longer matches the contents, but Firefox doesn't care.
|
136
assets/download/firefox-open-exe/FirefoxOpenExePatch.ps1
Normal file
136
assets/download/firefox-open-exe/FirefoxOpenExePatch.ps1
Normal file
@ -0,0 +1,136 @@
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory = $true, Position = 0)]
|
||||
[System.IO.FileInfo] $FirefoxFolder
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
if (-Not (Test-Path -Path $FirefoxFolder -PathType Container)){
|
||||
throw "Folder does not exist."
|
||||
}
|
||||
|
||||
$OmniJa = Join-Path -Path $FirefoxFolder -ChildPath "omni.ja"
|
||||
$OmniJaOld = "$OmniJa.old"
|
||||
|
||||
if (-Not (Test-Path -Path $OmniJa -PathType Leaf)){
|
||||
throw "File 'omni.ja' was not found in the folder."
|
||||
}
|
||||
|
||||
function Apply-Patch {
|
||||
Param(
|
||||
[Parameter(Mandatory = $true, Position = 0)]
|
||||
[Byte[]] $Data,
|
||||
[Parameter(Mandatory = $true, Position = 1)]
|
||||
[Byte[]] $Search,
|
||||
[Parameter(Mandatory = $true, Position = 2)]
|
||||
[Byte[]] $Replace
|
||||
)
|
||||
|
||||
$Occurrences = 0
|
||||
|
||||
$SearchLength = $Search.Length
|
||||
$CheckLength = $Data.Length - $SearchLength
|
||||
|
||||
for($i = 0; $i -lt $CheckLength; $i++){
|
||||
if ($Data[$i] -ne $Search[0]){
|
||||
continue
|
||||
}
|
||||
|
||||
$Matches = $true
|
||||
|
||||
for($o = 1; $o -lt $SearchLength; $o++){
|
||||
if ($Data[$i + $o] -ne $Search[$o]){
|
||||
$Matches = $false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if ($Matches){
|
||||
for($o = 0; $o -lt $Replace.Length; $o++){
|
||||
$Data[$i + $o] = $Replace[$o]
|
||||
}
|
||||
|
||||
$i += $Replace.Length
|
||||
$Occurrences++
|
||||
}
|
||||
}
|
||||
|
||||
return $Occurrences
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Patching omni.ja..."
|
||||
Write-Host ""
|
||||
|
||||
[Byte[]] $Data = [System.IO.File]::ReadAllBytes($OmniJa)
|
||||
$Occurrences = 0
|
||||
|
||||
$BytesSearch1 = [Byte[]](
|
||||
0x74, 0x68, 0x69, 0x73, 0x2E, 0x6D, 0x4C, 0x61, 0x75, 0x6E, 0x63, 0x68, 0x65, 0x72, 0x2E, 0x74, # this.mLauncher.t
|
||||
0x61, 0x72, 0x67, 0x65, 0x74, 0x46, 0x69, 0x6C, 0x65, 0x49, 0x73, 0x45, 0x78, 0x65, 0x63, 0x75, # argetFileIsExecu
|
||||
0x74, 0x61, 0x62, 0x6C, 0x65 # table
|
||||
)
|
||||
|
||||
$BytesReplace1 = [Byte[]](
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, #
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, #
|
||||
0x66, 0x61, 0x6C, 0x73, 0x65 # false
|
||||
)
|
||||
|
||||
$Attempt = Apply-Patch $Data $BytesSearch1 $BytesReplace1
|
||||
$Occurrences += $Attempt
|
||||
|
||||
if ($Attempt -eq 1){ # most likely the occurrence added by second patch
|
||||
Write-Host "It appears this installation is already patched."
|
||||
exit
|
||||
}
|
||||
|
||||
if ($Attempt -eq 0){
|
||||
Write-Host "Found nothing to patch."
|
||||
exit
|
||||
}
|
||||
|
||||
$BytesSearch2a = [Byte[]](
|
||||
0x0A, 0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, # \n ){\n /
|
||||
0x2F, 0x20, 0x4F, 0x70, 0x65, 0x6E, 0x20, 0x28, 0x75, 0x73, 0x69, 0x6E, 0x67, 0x20, 0x73, 0x79, # / Open (using sy
|
||||
0x73, 0x74, 0x65, 0x6D, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C # stem defaul
|
||||
)
|
||||
|
||||
$BytesReplace2a = [Byte[]](
|
||||
0x7C, 0x7C, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x6D, 0x4C, 0x61, 0x75, 0x6E, 0x63, 0x68, 0x65, 0x72, # ||this.mLauncher
|
||||
0x2E, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x46, 0x69, 0x6C, 0x65, 0x49, 0x73, 0x45, 0x78, 0x65, # .targetFileIsExe
|
||||
0x63, 0x75, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x29, 0x7B, 0x2F, 0x2F # cutable){//
|
||||
)
|
||||
|
||||
$BytesSearch2b = [Byte[]](
|
||||
0x29, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2F, 0x2F, 0x20, 0x4F, 0x70, 0x65, # ) {\n // Ope
|
||||
0x6E, 0x20, 0x28, 0x75, 0x73, 0x69, 0x6E, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x20, # n (using system
|
||||
0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x29, 0x2E # default).
|
||||
)
|
||||
|
||||
$BytesReplace2b = [Byte[]](
|
||||
0x7C, 0x7C, 0x74, 0x68, 0x69, 0x73, 0x2E, 0x6D, 0x4C, 0x61, 0x75, 0x6E, 0x63, 0x68, 0x65, 0x72, # ||this.mLauncher
|
||||
0x2E, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x46, 0x69, 0x6C, 0x65, 0x49, 0x73, 0x45, 0x78, 0x65, # .targetFileIsExe
|
||||
0x63, 0x75, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x29, 0x7B # cutable){
|
||||
)
|
||||
|
||||
$Attempt = Apply-Patch $Data $BytesSearch2a $BytesReplace2a
|
||||
|
||||
if ($Attempt -eq 0){ # older versions
|
||||
$Attempt = Apply-Patch $Data $BytesSearch2b $BytesReplace2b
|
||||
}
|
||||
|
||||
$Occurrences += $Attempt
|
||||
|
||||
if ($Occurrences -gt 0){
|
||||
Move-Item -Path $OmniJa -Destination $OmniJaOld -Force
|
||||
[System.IO.File]::WriteAllBytes($OmniJa, $Data)
|
||||
|
||||
Write-Host "Applied $Occurrences patches."
|
||||
Write-Host "Delete 'compatibility.ini' from your Firefox profile folder to regenerate the download dialog."
|
||||
Write-Host "The original 'omni.ja' file is backed up as 'omni.ja.old'."
|
||||
}
|
||||
else{
|
||||
Write-Host "Found nothing to patch."
|
||||
}
|
BIN
assets/img/firefox-open-exe/after.png
Normal file
BIN
assets/img/firefox-open-exe/after.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 25 KiB |
BIN
assets/img/firefox-open-exe/before.png
Normal file
BIN
assets/img/firefox-open-exe/before.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 20 KiB |
Loading…
Reference in New Issue
Block a user