Last active
May 20, 2021 20:19
-
-
Save aplocher/7d717925fe00c6602bed to your computer and use it in GitHub Desktop.
Patch router firmware files for WNDR3800SW (SureWest specific) router model. Can convert any Netgear WNDR3800 firmware img to work with WNDR3800SW. Requires perl.exe currently.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
== patch3800sw.ps1 == | |
Requires perl.exe to be in the same folder or in the environment PATH (for generating checksum)! | |
Patch firmware .img files used for Netgear WNDR3800 routers to work with Netgear WNDR3800SW | |
The SW model routers are specfic to SureWest Communications (ISP from northern CA) | |
The routers are identical, but require a different header on the .img file. This should work with any | |
.img file that works with a WNDR3800, including DD-WRT, OpenWRT, and the Netgear factory firmware | |
-- Example Command (PowerShell): | |
PS C:\Temp> .\patch3800sw.ps1 "C:\users\adam\Downloads\openwrt-ar71xx-generic-wndr3800-squashfs-factory(2).img" "C:\temp\test333.img" | |
-- Example Result: | |
=========================================================== | |
PATCHING INPUT FILE FOR SUREWEST NETGEAR WNDR3800SW ROUTERS | |
=========================================================== | |
-Reading input file | |
-Removing existing checksum byte | |
-Patching first 128 bytes of file with WNDR3800SW signature | |
-Attempting to generate new checksum byte | |
-Perl.exe found, generating and executing script | |
* Append checksum => file : C:\Users\adam\AppData\Local\Temp\tmp5794.tmp, len : 0x340084, checksum : 0x63 | |
-Finished | |
-New file - C:\temp\test333.img | |
-Patched and ready to flash on WNDR3800SW (if there weren't any errors) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# REQUIRES PERL.EXE! | |
# | |
# Patch firmware .img files used for Netgear WNDR3800 routers to work with Netgear WNDR3800SW | |
# The SW model routers are specfic to SureWest Communications (ISP from northern CA) | |
# The routers are identical, but require a different header on the .img file. This should work with any | |
# .img file that works with a WNDR3800, including DD-WRT, OpenWRT, and the Netgear factory firmware | |
# | |
## Usage: .\patch3800sw <input img file path> <output img file path> | |
# | |
## Example: .\patch3800sw openwrt-ar71xx-generic-wndr3800-squashfs-factory.img openwrt-wndr3800sw.img | |
# | |
## Requires: perl.exe must be installed or in the same folder as this script! | |
# | |
## Find updates at http://gist.github.com/aplocher | |
# | |
## All actual reverse engineering/hacking/whatevering was done by the folks over at OpenWRT.org. They | |
## deserve all the real credit https://forum.openwrt.org/viewtopic.php?id=39142 | |
# | |
## If anyone would like to port the perl script portion over to PowerShell, I would be happy to update | |
## this with your contributions. I hate requiring perl.exe! | |
Param( | |
[string]$fwImgInputPath, | |
[string]$fwImgOutputPath | |
) | |
Write-Output "===========================================================" | |
Write-Output "PATCHING INPUT FILE FOR SUREWEST NETGEAR WNDR3800SW ROUTERS" | |
Write-Output "===========================================================" | |
$fwImgInputPath = Convert-Path $fwImgInputPath | |
if ($fwImgInputPath -eq $null -or $fwImgInputPath -eq "" -or -not (Test-Path $fwImgInputPath)) { Write-Error "File not found"; Exit; } | |
$newBytes = 0x64,0x65,0x76,0x69,0x63,0x65,0x3A,0x57,0x4E,0x44,0x52,0x33,0x38,0x30,0x30,0x53,0x57,0x0A,0x76,0x65,0x72,0x73,0x69,0x6F,0x6E,0x3A,0x56,0x31, | |
0x2E,0x30,0x2E,0x30,0x2E,0x39,0x39,0x53,0x57,0x0A,0x72,0x65,0x67,0x69,0x6F,0x6E,0x3A,0x0A,0x68,0x64,0x5F,0x69,0x64,0x3A,0x32,0x39,0x37,0x36, | |
0x33,0x36,0x35,0x34,0x2B,0x31,0x36,0x2B,0x31,0x32,0x38,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | |
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | |
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 | |
Write-Output "-Reading input file" | |
$inputFileBytes = [System.IO.File]::ReadAllBytes($fwImgInputPath) | |
$bytes = $inputFileBytes[1..($inputFileBytes.Length-1)] | |
Write-Output "-Removing existing checksum byte" | |
[array]::Copy($inputFileBytes, $bytes, $bytes.Length) | |
Write-Output "-Patching first 128 bytes of file with WNDR3800SW signature" | |
[array]::Copy($newBytes,0,$bytes,0,128) | |
New-Item $fwImgOutputPath -Force -ea SilentlyContinue | Out-Null | |
$fwImgOutputPath = Convert-Path $fwImgOutputPath | |
[System.IO.File]::WriteAllBytes($fwImgOutputPath, $bytes) | |
Write-Output "-Attempting to generate new checksum byte" | |
$perlExe = "perl.exe" | |
if (Get-Command ".\perl.exe" -ea SilentlyContinue) {$perlExe = ".\perl.exe"} | |
if ((Get-Command "$($perlExe)" -ea SilentlyContinue) -ne $null) { | |
Write-Output "-Perl.exe found, generating and executing script" | |
$perlPath = (Get-Command $perlExe).Path | |
$perlScript = "#!/usr/bin/perl -w` | |
` | |
use strict;` | |
` | |
my `$TempCompFileName = shift(@ARGV);` | |
my `$OutFileName = shift(@ARGV);` | |
` | |
my (`$start_addr, `$appd_cks, `$appd_len) = (0);` | |
` | |
sub appendCks` | |
{` | |
my (`$fileName) = @_;` | |
my (`$cks, `$len) = (0, 0);` | |
` | |
open APPENDCKS_FH, `"+<`$fileName`" or die `"fail to open file `$fileName : `$!`";` | |
until ( eof APPENDCKS_FH ) {` | |
`$cks = ( `$cks + ord( getc( APPENDCKS_FH )) ) % 0x100 ;` | |
`$len++ ;` | |
}` | |
` | |
`$cks = 0xFF - `$cks;` | |
close APPENDCKS_FH;` | |
` | |
printf (`" * Append checksum => file : %s, len : 0x%X, checksum : 0x%X \n`", , `$fileName, `$len, `$cks);` | |
`$appd_cks =`$cks;` | |
`$appd_len =`$len;` | |
}` | |
` | |
` | |
appendCks(`$TempCompFileName);` | |
` | |
# Then append Checksum (include the 4bytes starting address) ` | |
open INS_FH, `"`$TempCompFileName`" or die `"fail to open file `$TempCompFileName : `$!`";` | |
open OUT_FH, `">`$OutFileName`" or die `"fail to Append file `$OutFileName: `$!`";` | |
while (<INS_FH>)` | |
{` | |
print OUT_FH `$_;` | |
}` | |
print OUT_FH chr(`$appd_cks); ` | |
close INS_FH;` | |
close OUT_FH;" | |
$checksumPlPath = Join-Path $env:TEMP "GenChecksum.pl" | |
$newPerlPath = Join-Path $env:TEMP "newperl.exe" | |
Copy-Item -Force $perlPath $newPerlPath | |
$perlScript | Out-File $checksumPlPath -Force | |
$tmp = New-TemporaryFile | |
Move-Item "$($fwImgOutputPath)" "$($tmp)" -Force | |
c:\windows\system32\cmd.exe /c ""$perlPath" "$($checksumPlPath)" "$($tmp)" "$($fwImgOutputPath)"" | |
Write-Output "-Finished" | |
Write-Output "-New file - $($fwImgOutputPath)" | |
Write-Output "-Patched and ready to flash on WNDR3800SW (if there weren't any errors)" | |
} | |
else { | |
Write-Warning "-Perl.exe not found. New file generated but no valid checksum byte created" | |
Write-Output "-New file: $($fwImgOutputPath)" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice! I used geoffch's C version. Saved my ass when I ended up with a used WNDR3800 from ebay that turned out to be a WNDR3800SW. Worked flawlessly. Thanks guys!