Last active
May 9, 2020 14:23
-
-
Save ysc3839/b2c5daa6934e8ff78724a1c7f3c0d929 to your computer and use it in GitHub Desktop.
MiWiFi R3 Firmware Mod
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
import sys, os | |
from zlib import crc32 | |
from shutil import copyfileobj | |
from struct import calcsize | |
from io import SEEK_END | |
### uImage Header | |
### 64-byte header structure: | |
### uint32 magic_number | |
### uint32 header_crc | |
### uint32 timestamp | |
### uint32 uImage_size | |
### uint32 load_address | |
### uint32 entry_address | |
### uint32 data_crc | |
### uint8 os_type | |
### uint8 architecture | |
### uint8 image_type | |
### uint8 compression_type | |
### uint8 image_name[32] | |
HEADER_FORMAT = '!7L4B32s' ### (Big-endian, 7 ULONGS, 4 UCHARs, 32-byte string) | |
HEADER_SIZE = calcsize(HEADER_FORMAT) ### Should be 64-bytes | |
HEADER_MAGIC = 0x27051956 | |
KERNEL_SIZE = 0x140000 | |
KERNEL_PART_SIZE = 0x400000 | |
CHUNK_SIZE = 16 * 1024 | |
def pad_file(f, size, byte=0x00): | |
fsize = f.seek(0, SEEK_END) | |
remaining_size = size - fsize | |
while remaining_size > 0: | |
write_size = CHUNK_SIZE if remaining_size > CHUNK_SIZE else remaining_size | |
written = f.write(bytes([byte]) * write_size) | |
remaining_size -= written | |
def modify(trx_filename, mod_filename): | |
infile = open(trx_filename, 'rb') | |
outfile = open(mod_filename, 'xb') | |
hdr_data = infile.read(HEADER_SIZE) | |
outfile.write(bytes(HEADER_SIZE)) | |
remaining_size = KERNEL_SIZE - HEADER_SIZE | |
crc32_sum = 0 | |
while remaining_size > 0: | |
chunk = infile.read(CHUNK_SIZE) | |
if not chunk: raise EOFError('early end of file') | |
if len(chunk) > remaining_size: chunk = chunk[:remaining_size] | |
crc32_sum = crc32(chunk, crc32_sum) | |
outfile.write(chunk) | |
remaining_size -= len(chunk) | |
crc32_bytes = crc32_sum.to_bytes(4, 'big') | |
pad_file(outfile, KERNEL_PART_SIZE, 0xFF) | |
infile.seek(0) | |
copyfileobj(infile, outfile) | |
size_bytes = (KERNEL_SIZE - HEADER_SIZE).to_bytes(4, 'big') | |
hdr_data = hdr_data[:4] + bytes(4) + hdr_data[8:12] + size_bytes + hdr_data[16:24] + crc32_bytes + hdr_data[28:] | |
hdr_crc32 = crc32(hdr_data).to_bytes(4, 'big') | |
outfile.seek(0) | |
outfile.write(hdr_data) | |
outfile.seek(4) | |
outfile.write(hdr_crc32) | |
infile.close() | |
outfile.close() | |
def main(): | |
if len(sys.argv) > 1: | |
trx_filename = sys.argv[1] | |
ext = os.path.splitext(trx_filename) | |
mod_filename = ext[0] + '.mod' + ext[1] | |
modify(trx_filename, mod_filename) | |
else: | |
print('Usage: padavan_mod.py trx_file') | |
return | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment