mirror of
https://github.com/elseif/MikroTikPatch
synced 2026-07-17 10:39:40 +00:00
modified: .gitignore
modified: README.md modified: npk.py modified: patch.py
This commit is contained in:
parent
1861785032
commit
6c96e51b24
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
__pycache__/
|
__pycache__/
|
||||||
venv/
|
venv/
|
||||||
|
patch_*.py
|
||||||
@ -7,6 +7,15 @@
|
|||||||
|
|
||||||
### Uses keygen to generate license key (keygen in iso or img).
|
### Uses keygen to generate license key (keygen in iso or img).
|
||||||

|

|
||||||
|
|
||||||
|
### npk.py
|
||||||
|
Sign,Verify,Create, Extract npk file.
|
||||||
|
### patch.py
|
||||||
|
Patch public key and sign NPK files
|
||||||
|
### netinstall.py
|
||||||
|
Modify netinstallexe to enable network installation of NPK files that have been resigned in ISO
|
||||||
|
### upgrade.py
|
||||||
|
By adding static domain name resolution in RouterOS, the NPK file that has been resigned in ISO can be installed during the upgrade process.
|
||||||
### all patches are applied automatically with [github workflow](https://github.com/elseif/MikroTikPatch/blob/main/.github/workflows/mikrotik_patch.yml).
|
### all patches are applied automatically with [github workflow](https://github.com/elseif/MikroTikPatch/blob/main/.github/workflows/mikrotik_patch.yml).
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
7
npk.py
7
npk.py
@ -239,14 +239,7 @@ class NovaPackage:
|
|||||||
assert int.from_bytes(data[4:8],'little') == len(data) - 8, 'Invalid Nova Package Size'
|
assert int.from_bytes(data[4:8],'little') == len(data) - 8, 'Invalid Nova Package Size'
|
||||||
return NovaPackage(data[8:])
|
return NovaPackage(data[8:])
|
||||||
|
|
||||||
def get_latest_version(channel:str) -> str:
|
|
||||||
import requests
|
|
||||||
response = requests.get(f'https://upgrade.mikrotik.com/routeros/NEWESTa7.{channel}')
|
|
||||||
return response.text.split(' ')[0]
|
|
||||||
|
|
||||||
def create_option_npk(npk_file:str,squashfs_file:str)->NovaPackage:
|
|
||||||
|
|
||||||
return option_npk
|
|
||||||
|
|
||||||
if __name__=='__main__':
|
if __name__=='__main__':
|
||||||
import argparse,os
|
import argparse,os
|
||||||
|
|||||||
72
patch.py
72
patch.py
@ -64,36 +64,40 @@ def patch_squashfs(path,key_dict):
|
|||||||
data = data.replace(old_public_key,new_public_key)
|
data = data.replace(old_public_key,new_public_key)
|
||||||
open(file,'wb').write(data)
|
open(file,'wb').write(data)
|
||||||
|
|
||||||
def patch_system_npk(key_dict,input_file,output_file=None):
|
def patch_npk_file(key_dict,kcdsa_private_key,eddsa_private_key,input_file,output_file=None):
|
||||||
npk = NovaPackage.load(input_file)
|
npk = NovaPackage.load(input_file)
|
||||||
file_container = NpkFileContainer.unserialize_from(npk[NpkPartID.FILE_CONTAINER].data)
|
if npk[NpkPartID.NAME_INFO].data.name == 'system':
|
||||||
for item in file_container:
|
file_container = NpkFileContainer.unserialize_from(npk[NpkPartID.FILE_CONTAINER].data)
|
||||||
if item.name == b'boot/EFI/BOOT/BOOTX64.EFI':
|
for item in file_container:
|
||||||
print(f'patch {item.name} ...')
|
if item.name == b'boot/EFI/BOOT/BOOTX64.EFI':
|
||||||
item.data = patch_bzimage(item.data,key_dict)
|
print(f'patch {item.name} ...')
|
||||||
open('linux','wb').write(item.data)
|
item.data = patch_bzimage(item.data,key_dict)
|
||||||
break
|
open('linux','wb').write(item.data)
|
||||||
npk[NpkPartID.FILE_CONTAINER].data = file_container.serialize()
|
elif item.name == b'boot/kernel':
|
||||||
try:
|
from netinstall import patch_elf
|
||||||
squashfs_file = 'squashfs.sfs'
|
print(f'patch {item.name} ...')
|
||||||
extract_dir = 'squashfs-root'
|
item.data = patch_elf(item.data,key_dict)
|
||||||
open(squashfs_file,'wb').write(npk[NpkPartID.SQUASHFS].data)
|
open('linux','wb').write(item.data)
|
||||||
print(f"extract {squashfs_file} ...")
|
npk[NpkPartID.FILE_CONTAINER].data = file_container.serialize()
|
||||||
_, stderr = run_shell_command(f"unsquashfs -d {extract_dir} {squashfs_file}")
|
try:
|
||||||
print(stderr.decode())
|
squashfs_file = 'squashfs.sfs'
|
||||||
patch_squashfs(extract_dir,key_dict)
|
extract_dir = 'squashfs-root'
|
||||||
print(f"pack {extract_dir} ...")
|
open(squashfs_file,'wb').write(npk[NpkPartID.SQUASHFS].data)
|
||||||
|
print(f"extract {squashfs_file} ...")
|
||||||
|
_, stderr = run_shell_command(f"unsquashfs -d {extract_dir} {squashfs_file}")
|
||||||
|
print(stderr.decode())
|
||||||
|
patch_squashfs(extract_dir,key_dict)
|
||||||
|
print(f"pack {extract_dir} ...")
|
||||||
|
run_shell_command(f"rm -f {squashfs_file}")
|
||||||
|
_, stderr = run_shell_command(f"mksquashfs {extract_dir} {squashfs_file} -quiet -comp xz -no-xattrs -b 256k")
|
||||||
|
print(stderr.decode())
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
print(f"clean ...")
|
||||||
|
run_shell_command(f"rm -rf {extract_dir}")
|
||||||
|
npk[NpkPartID.SQUASHFS].data = open(squashfs_file,'rb').read()
|
||||||
run_shell_command(f"rm -f {squashfs_file}")
|
run_shell_command(f"rm -f {squashfs_file}")
|
||||||
_, stderr = run_shell_command(f"mksquashfs {extract_dir} {squashfs_file} -quiet -comp xz -no-xattrs -b 256k")
|
|
||||||
print(stderr.decode())
|
|
||||||
except Exception as e:
|
|
||||||
print(e)
|
|
||||||
print(f"clean ...")
|
|
||||||
run_shell_command(f"rm -rf {extract_dir}")
|
|
||||||
npk[NpkPartID.SQUASHFS].data = open(squashfs_file,'rb').read()
|
|
||||||
run_shell_command(f"rm -f {squashfs_file}")
|
|
||||||
kcdsa_private_key = bytes.fromhex(os.environ['CUSTOM_LICENSE_PRIVATE_KEY'])
|
|
||||||
eddsa_private_key = bytes.fromhex(os.environ['CUSTOM_NPK_SIGN_PRIVATE_KEY'])
|
|
||||||
npk.sign(kcdsa_private_key,eddsa_private_key)
|
npk.sign(kcdsa_private_key,eddsa_private_key)
|
||||||
npk.save(output_file or input_file)
|
npk.save(output_file or input_file)
|
||||||
|
|
||||||
@ -101,26 +105,26 @@ if __name__ == '__main__':
|
|||||||
import argparse,os
|
import argparse,os
|
||||||
parser = argparse.ArgumentParser(description='MikroTik patcher')
|
parser = argparse.ArgumentParser(description='MikroTik patcher')
|
||||||
subparsers = parser.add_subparsers(dest="command")
|
subparsers = parser.add_subparsers(dest="command")
|
||||||
npk_parser = subparsers.add_parser('npk',help='patch routeros.npk file')
|
npk_parser = subparsers.add_parser('npk',help='patch and sign npk file')
|
||||||
npk_parser.add_argument('input',type=str, help='Input file')
|
npk_parser.add_argument('input',type=str, help='Input file')
|
||||||
npk_parser.add_argument('-o','--output',type=str,help='Output file')
|
npk_parser.add_argument('-o','--output',type=str,help='Output file')
|
||||||
|
|
||||||
netinstall_parser = subparsers.add_parser('netinstall',help='patch netinstall file')
|
netinstall_parser = subparsers.add_parser('netinstall',help='patch netinstall file')
|
||||||
netinstall_parser.add_argument('input',type=str, help='Input file')
|
netinstall_parser.add_argument('input',type=str, help='Input file')
|
||||||
netinstall_parser.add_argument('-o','--output',type=str,help='Output file')
|
netinstall_parser.add_argument('-o','--output',type=str,help='Output file')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
key_dict = {
|
key_dict = {
|
||||||
bytes.fromhex(os.environ['MIKRO_LICENSE_PUBLIC_KEY']):bytes.fromhex(os.environ['CUSTOM_LICENSE_PUBLIC_KEY']),
|
bytes.fromhex(os.environ['MIKRO_LICENSE_PUBLIC_KEY']):bytes.fromhex(os.environ['CUSTOM_LICENSE_PUBLIC_KEY']),
|
||||||
bytes.fromhex(os.environ['MIKRO_NPK_SIGN_PUBLIC_LKEY']):bytes.fromhex(os.environ['CUSTOM_NPK_SIGN_PUBLIC_KEY'])
|
bytes.fromhex(os.environ['MIKRO_NPK_SIGN_PUBLIC_LKEY']):bytes.fromhex(os.environ['CUSTOM_NPK_SIGN_PUBLIC_KEY'])
|
||||||
}
|
}
|
||||||
|
kcdsa_private_key = bytes.fromhex(os.environ['CUSTOM_LICENSE_PRIVATE_KEY'])
|
||||||
|
eddsa_private_key = bytes.fromhex(os.environ['CUSTOM_NPK_SIGN_PRIVATE_KEY'])
|
||||||
if args.command =='npk':
|
if args.command =='npk':
|
||||||
print(f'patching {args.input} ...')
|
print(f'patching {args.input} ...')
|
||||||
patch_system_npk(key_dict,args.input)
|
patch_npk_file(key_dict,kcdsa_private_key,eddsa_private_key,args.input,args.output)
|
||||||
elif args.command == 'netinstall':
|
elif args.command == 'netinstall':
|
||||||
from netinstall import patch_netinstall
|
from netinstall import patch_netinstall
|
||||||
print(f'patching {args.input} ...')
|
print(f'patching {args.input} ...')
|
||||||
patch_netinstall(key_dict,args.input)
|
patch_netinstall(key_dict,args.input,args.output)
|
||||||
else:
|
else:
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user