From 1aa628768d05e158a251daeaf2742982e770d26d Mon Sep 17 00:00:00 2001 From: Dual Tachyon Date: Tue, 5 Sep 2023 22:16:42 +0100 Subject: [PATCH] Support for packed firmware. --- .github/workflows/main.yaml | 5 ++++- .github/workflows/release.yaml | 7 ++++-- Makefile | 1 + fw-pack.py | 40 ++++++++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 3 deletions(-) create mode 100755 fw-pack.py diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 2aeba2b..4a24b3c 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -11,6 +11,9 @@ jobs: with: release: '10.3-2021.10' + - name: Install Python dependencies + run: python -m pip install --upgrade pip crcmod + - name: Checkout uses: actions/checkout@v3 @@ -27,5 +30,5 @@ jobs: uses: actions/upload-artifact@v3 with: name: firmware - path: firmware.bin + path: firmware*.bin diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index edcf1dd..86b9241 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -13,6 +13,9 @@ jobs: with: release: '10.3-2021.10' + - name: Install Python dependencies + run: python3 -m pip install --upgrade pip crcmod + - name: Checkout uses: actions/checkout@v3 @@ -29,10 +32,10 @@ jobs: uses: actions/upload-artifact@v3 with: name: firmware - path: firmware.bin + path: firmware*.bin - name: 'Create Release' uses: ncipollo/release-action@v1 with: - artifacts: "firmware.bin" + artifacts: "firmware*.bin" diff --git a/Makefile b/Makefile index f00c9fb..5ef092e 100755 --- a/Makefile +++ b/Makefile @@ -107,6 +107,7 @@ DEPS = $(OBJS:.o=.d) all: $(TARGET) $(OBJCOPY) -O binary $< $<.bin + ./fw-pack.py $<.bin $(GIT_HASH) $<.packed.bin $(SIZE) $< debug: diff --git a/fw-pack.py b/fw-pack.py new file mode 100755 index 0000000..a3e6127 --- /dev/null +++ b/fw-pack.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 + +import crcmod +import sys + +from itertools import cycle +from binascii import hexlify + +OBFUSCATION = [ + 0x47, 0x22, 0xC0, 0x52, 0x5D, 0x57, 0x48, 0x94, 0xB1, 0x60, 0x60, 0xDB, 0x6F, 0xE3, 0x4C, 0x7C, + 0xD8, 0x4A, 0xD6, 0x8B, 0x30, 0xEC, 0x25, 0xE0, 0x4C, 0xD9, 0x00, 0x7F, 0xBF, 0xE3, 0x54, 0x05, + 0xE9, 0x3A, 0x97, 0x6B, 0xB0, 0x6E, 0x0C, 0xFB, 0xB1, 0x1A, 0xE2, 0xC9, 0xC1, 0x56, 0x47, 0xE9, + 0xBA, 0xF1, 0x42, 0xB6, 0x67, 0x5F, 0x0F, 0x96, 0xF7, 0xC9, 0x3C, 0x84, 0x1B, 0x26, 0xE1, 0x4E, + 0x3B, 0x6F, 0x66, 0xE6, 0xA0, 0x6A, 0xB0, 0xBF, 0xC6, 0xA5, 0x70, 0x3A, 0xBA, 0x18, 0x9E, 0x27, + 0x1A, 0x53, 0x5B, 0x71, 0xB1, 0x94, 0x1E, 0x18, 0xF2, 0xD6, 0x81, 0x02, 0x22, 0xFD, 0x5A, 0x28, + 0x91, 0xDB, 0xBA, 0x5D, 0x64, 0xC6, 0xFE, 0x86, 0x83, 0x9C, 0x50, 0x1C, 0x73, 0x03, 0x11, 0xD6, + 0xAF, 0x30, 0xF4, 0x2C, 0x77, 0xB2, 0x7D, 0xBB, 0x3F, 0x29, 0x28, 0x57, 0x22, 0xD6, 0x92, 0x8B, + ] + +def obfuscate(fw): + return bytes([a^b for a, b in zip(fw, cycle(OBFUSCATION))]) + +plain = open(sys.argv[1], 'rb').read() +if len(sys.argv[2]) > 10: + print('Version suffix is too big!') + sys.exit(1) + +version = b'*OEFW-' + bytes(sys.argv[2], 'ascii') +if len(version) < 16: + version += b'\x00' * (16 - len(version)) + +packed = obfuscate(plain[:0x2000] + version + plain[0x2000:]) + +crc = crcmod.predefined.Crc('xmodem') +crc.update(packed) +digest = crc.digest() +digest = bytes([digest[1], digest[0]]) + +open(sys.argv[3], 'wb').write(packed + digest) +