From 2fe3072ecf84b7e8de31bc132817adc686e6c48f Mon Sep 17 00:00:00 2001 From: zyb Date: Sun, 14 Jul 2024 06:32:48 +0800 Subject: [PATCH] modified: .github/workflows/mikrotik_patch.yml modified: netinstall.py --- .github/workflows/mikrotik_patch.yml | 13 ++- netinstall.py | 162 ++++++++++++++++++--------- 2 files changed, 119 insertions(+), 56 deletions(-) diff --git a/.github/workflows/mikrotik_patch.yml b/.github/workflows/mikrotik_patch.yml index f8748b1..9af3360 100644 --- a/.github/workflows/mikrotik_patch.yml +++ b/.github/workflows/mikrotik_patch.yml @@ -105,8 +105,6 @@ jobs: sudo mksquashfs python python3.sfs -quiet -comp xz -no-xattrs -b 256k sudo rm -rf ./python - - - name: Cache NetInstall ${{ env.LATEST_VERSION }} if: matrix.arch == 'x86_64' id: cache-netinstall @@ -114,19 +112,24 @@ jobs: with: path: | netinstall.zip + netinstall.tar.gz key: netinstall-${{ env.LATEST_VERSION }} - - name: Get netinstall-${{ env.LATEST_VERSION }}.zip + - name: Get netinstall ${{ env.LATEST_VERSION }} if: matrix.arch == 'x86_64' && steps.cache-netinstall.outputs.cache-hit != 'true' run: | sudo wget -nv -O netinstall.zip https://download.mikrotik.com/routeros/$LATEST_VERSION/netinstall-$LATEST_VERSION.zip + sudo wget -nv -O netinstall.tar.gz https://download.mikrotik.com/routeros/$LATEST_VERSION/netinstall-$LATEST_VERSION.tar.gz - - name: Patch netinstall.exe + - name: Patch netinstall ${{ env.LATEST_VERSION }} if: matrix.arch == 'x86_64' run: | sudo unzip netinstall.zip sudo -E python3 patch.py netinstall netinstall.exe sudo zip netinstall-$LATEST_VERSION.zip ./netinstall.exe + sudo tar -xvf netinstall.tar.gz + sudo -E python3 patch.py netinstall netinstall-cli + sudo tar -czvf netinstall-$LATEST_VERSION.tar.gz ./netinstall-cli - name: Cache mikrotik-${{ env.LATEST_VERSION }}${{ env.ARCH }}.iso id: cache-mikrotik @@ -410,7 +413,7 @@ jobs: files: | mikrotik-${{ env.LATEST_VERSION }}${{ env.ARCH }}.iso chr-${{ env.LATEST_VERSION }}*.zip - netinstall-${{ env.LATEST_VERSION }}.zip + netinstall-${{ env.LATEST_VERSION }}.* install-image-${{ env.LATEST_VERSION }}.zip routeros-${{ env.LATEST_VERSION }}${{ env.ARCH }}.npk option-${{ env.LATEST_VERSION }}${{ env.ARCH }}.npk diff --git a/netinstall.py b/netinstall.py index 27c0d9c..2a625f2 100644 --- a/netinstall.py +++ b/netinstall.py @@ -1,15 +1,16 @@ import struct,lzma -ROUTEROS_BOOT = { - 129:{'arch':'power','name':'Powerboot','filter':lzma.FILTER_POWERPC}, - 130:{'arch':'e500','name':'e500_boot'}, - 131:{'arch':'mips','name':'Mips_boot'}, - 135:{'arch':'400','name':'440__boot'}, - 136:{'arch':'tile','name':'tile_boot'}, - 137:{'arch':'arm','name':'ARM__boot','filter':lzma.FILTER_ARMTHUMB}, - 138:{'arch':'mmips','name':'MMipsBoot'}, - 139:{'arch':'arm64','name':'ARM64__boot','filter':lzma.FILTER_ARMTHUMB}, - 143:{'arch':'x86_64','name':'x86_64boot'} -} +# ROUTEROS_BOOT = { +# 129:{'arch':'power','name':'Powerboot','filter':lzma.FILTER_POWERPC}, +# 130:{'arch':'e500','name':'e500_boot'}, +# 131:{'arch':'mips','name':'Mips_boot'}, +# 135:{'arch':'400','name':'440__boot'}, +# 136:{'arch':'tile','name':'tile_boot'}, +# 137:{'arch':'arm','name':'ARM__boot','filter':lzma.FILTER_ARMTHUMB}, +# 138:{'arch':'mmips','name':'MMipsBoot'}, +# 139:{'arch':'arm64','name':'ARM64__boot','filter':lzma.FILTER_ARMTHUMB}, +# 143:{'arch':'x86_64','name':'x86_64boot'} +# } + def find_7zXZ_data(data:bytes): offset1 = 0 _data = data @@ -19,13 +20,13 @@ def find_7zXZ_data(data:bytes): offset1 -= 8 offset2 = 0 _data = data - while b'\x00\x01\x59\x5A' in _data: - offset2 = offset2 + _data.index(b'\x00\x01\x59\x5A') + 4 + while b'\x00\x00\x00\x00\x01\x59\x5A' in _data: + offset2 = offset2 + _data.index(b'\x00\x00\x00\x00\x01\x59\x5A') + 7 _data = _data[offset2:] offset2 return data[offset1:offset2] -def patch_elf(data: bytes,key_dict:dict,filter=None): +def patch_elf(data: bytes,key_dict:dict): initrd_xz = find_7zXZ_data(data) initrd = lzma.decompress(initrd_xz) new_initrd = initrd @@ -34,7 +35,7 @@ def patch_elf(data: bytes,key_dict:dict,filter=None): print(f'initramfs public key patched {old_public_key[:16].hex().upper()}...') new_initrd = new_initrd.replace(old_public_key,new_public_key) - filters=[{"id":filter},{"id": lzma.FILTER_LZMA2, "preset": 9,}] if filter else [{"id": lzma.FILTER_LZMA2, "preset": 9,}] + filters=[{"id": lzma.FILTER_LZMA2, "preset": 9,}] new_initrd_xz = lzma.compress(new_initrd,check=lzma.CHECK_CRC32,filters=filters) assert len(new_initrd_xz) <= len(initrd_xz),'new initrd xz size is too big' @@ -42,13 +43,11 @@ def patch_elf(data: bytes,key_dict:dict,filter=None): new_data = data.replace(initrd_xz,new_initrd_xz) return new_data -def patch_pe(data: bytes,key_dict:dict,filter=None): - vmlinux_xz_offset = data.index(b'\xFD7zXZ\x00\x00\x01') - vmlinux_xz_size = data.index(b'\x00\x01\x59\x5A') + 4 - vmlinux_xz_offset - vmlinux_xz = data[vmlinux_xz_offset:vmlinux_xz_offset+vmlinux_xz_size] +def patch_pe(data: bytes,key_dict:dict): + vmlinux_xz = find_7zXZ_data(data) vmlinux = lzma.decompress(vmlinux_xz) initrd_xz_offset = vmlinux.index(b'\xFD7zXZ\x00\x00\x01') - initrd_xz_size = vmlinux.index(b'\x00\x01\x59\x5A') + 4 - initrd_xz_offset + initrd_xz_size = vmlinux[initrd_xz_offset:].index(b'\x00\x00\x00\x00\x01\x59\x5A') + 7 initrd_xz = vmlinux[initrd_xz_offset:initrd_xz_offset+initrd_xz_size] initrd = lzma.decompress(initrd_xz) new_initrd = initrd @@ -57,14 +56,13 @@ def patch_pe(data: bytes,key_dict:dict,filter=None): print(f'initrd public key patched {old_public_key[:16].hex().upper()}...') new_initrd = new_initrd.replace(old_public_key,new_public_key) - filters=[{"id":filter},{"id": lzma.FILTER_LZMA2, "preset": 9,}] if filter else [{"id": lzma.FILTER_LZMA2, "preset": 9,}] + filters= [{"id": lzma.FILTER_LZMA2, "preset": 9,}] new_initrd_xz = lzma.compress(new_initrd,check=lzma.CHECK_CRC32,filters=filters) assert len(new_initrd_xz) <= len(initrd_xz),'new initrd xz size is too big' new_initrd_xz = new_initrd_xz.ljust(len(initrd_xz),b'\0') new_vmlinux = vmlinux.replace(initrd_xz,new_initrd_xz) - filters=[{"id":filter},{"id": lzma.FILTER_LZMA2, "preset": 9,}] if filter else [{"id": lzma.FILTER_LZMA2, "preset": 9,}] new_vmlinux_xz = lzma.compress(new_vmlinux,check=lzma.CHECK_CRC32,filters=filters) assert len(new_vmlinux_xz) <= len(vmlinux_xz),'new vmlinux xz size is too big' @@ -75,34 +73,96 @@ def patch_pe(data: bytes,key_dict:dict,filter=None): def patch_netinstall(key_dict: dict,input_file,output_file=None): - import pefile - with pefile.PE(input_file) as pe: - for resource in pe.DIRECTORY_ENTRY_RESOURCE.entries: - if resource.id == pefile.RESOURCE_TYPE["RT_RCDATA"]: - for sub_resource in resource.directory.entries: - if sub_resource.id in ROUTEROS_BOOT: - bootloader = ROUTEROS_BOOT[sub_resource.id] - filter = bootloader.get("filter") - print(f'found {bootloader["arch"]}({sub_resource.id}) bootloader') - rva = sub_resource.directory.entries[0].data.struct.OffsetToData - size = sub_resource.directory.entries[0].data.struct.Size - data = pe.get_data(rva,size) - assert len(data) -4 >= struct.unpack_from('= struct.unpack_from('