Skip to content

Instantly share code, notes, and snippets.

@ariscop
Created February 24, 2015 00:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ariscop/428a44af327a7d1213c1 to your computer and use it in GitHub Desktop.
Save ariscop/428a44af327a7d1213c1 to your computer and use it in GitHub Desktop.
Extracts .ros firmware files used by some netgear swtiches, eg: ng_gs728_52tp_516tp_bx-60116.ros
#!/usr/bin/env python3
import sys
import lzma
import crcmod
from struct import unpack, iter_unpack
from collections import namedtuple
from functools import partial
from tabulate import tabulate
crc32 = crcmod.predefined.mkPredefinedCrcFun('crc-32')
rosHdr = namedtuple("rosHdr", "magic model version crc pad")
Nghdr = namedtuple("NG022", "magic unk0 unk1 unk2 unk3 type pad")
def to_hex(data):
if isinstance(data, int):
return hex(data)
return ''.join('%02x' % x for x in data)
def to_str(data):
try:
return bytes(data).decode().strip('\x00')
except:
return bytes(data)
def to_int(data):
return int.from_bytes(data, "little")
def decompress(data):
Decompressor = lzma.LZMADecompressor()
out = Decompressor.decompress(data)
return out
def ngunpack(data):
defer = []
table = []
count = unpack("<I", data[0x20:0x24])[0]
for name, offset, length, unknown, pad in iter_unpack("<16s 3I 4s", data[0x50:][:32*count]):
name = to_str(name)
length = length
table.append((name, hex(offset), hex(length), hex(unknown), to_hex(pad)))
if unknown == 0x0:
section = data[offset:][:length]
if unknown == 0x200:
section = data[offset:][0x20:length]
section = decompress(section)
defer.append((name, partial(ng022, data[offset:][:length])))
with open("out/"+name, "wb") as out:
out.write(section)
print()
print(tabulate(table, headers=("Name", "Offset", "length", "compressed?", "Padding")))
print()
print("Compressed:")
for name, func in defer:
print(name.ljust(12), end="")
func()
def ng022(data):
hdr = Nghdr(*unpack("<8s4I4s4s", data[:0x20]))
print(hdr[0].decode(), *[to_hex(x).ljust(10) for x in hdr[1:]])
if hdr.type == b'PACK':
ngunpack(data)
with open(sys.argv[1], "rb") as fd:
data = memoryview(fd.read())
hdr = rosHdr(*unpack(">4s 20s 20s I 16s", data[:0x40]))
print("hdr:", "%s (%s)" % (to_hex(hdr.magic), to_str(hdr.magic[:2])), sep='\t')
print("model:", to_str(hdr.model), sep='\t')
print("ver:", to_str(hdr.version), sep='\t')
print("crc:", hex(hdr.crc), sep='\t')
print("pad:", to_hex(hdr.pad), sep='\t')
if hdr.crc != crc32(data[0x40:]):
print("BAD CRC")
print()
ng022(data[0x40:])
exit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment