Created
February 24, 2015 00:25
-
-
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
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
#!/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