Compare commits

..

56 Commits

Author SHA1 Message Date
elseif
77f07bbf27 Update README.md
Signed-off-by: elseif <elseif@live.cn>
2025-09-25 09:45:43 +08:00
elseif
06a9d80798 Update README.md
Signed-off-by: elseif <elseif@live.cn>
2025-09-25 09:14:16 +08:00
elseif
3c2e1197ce Update chr.sh
Signed-off-by: elseif <elseif@live.cn>
2025-09-24 20:59:05 +08:00
elseif
befaa60509 Update README.md
Signed-off-by: elseif <elseif@live.cn>
2025-09-24 20:56:13 +08:00
elseif
1a2f73d363 Update README.md
Signed-off-by: elseif <elseif@live.cn>
2025-09-24 19:36:08 +08:00
elseif
e7063fdcbd Update README.md
Signed-off-by: elseif <elseif@live.cn>
2025-09-24 19:19:08 +08:00
elseif
b26437cb47 Update README.md
Signed-off-by: elseif <elseif@live.cn>
2025-09-24 18:30:41 +08:00
elseif
b6c24eb657 Update chr.sh
Signed-off-by: elseif <elseif@live.cn>
2025-09-24 18:21:53 +08:00
elseif
f1d3c640f8 Update README.md
Signed-off-by: elseif <elseif@live.cn>
2025-09-24 18:17:55 +08:00
elseif
2f627420a2 Update chr.sh
Signed-off-by: elseif <elseif@live.cn>
2025-09-24 14:16:40 +08:00
zyb
482041cac3 modified: index.html 2025-09-24 13:50:40 +08:00
zyb
c139e9012a modified: chr.sh 2025-09-24 13:31:41 +08:00
zyb
89e9e0a92e modified: chr.sh 2025-09-24 13:14:08 +08:00
zyb
9ad1b924a1 modified: chr.sh 2025-09-24 13:09:15 +08:00
elseif
68c53e4a19 Update README.md
Signed-off-by: elseif <elseif@live.cn>
2025-09-22 12:25:11 +08:00
elseif
e70a8aff16 Update README.md
Signed-off-by: elseif <elseif@live.cn>
2025-09-22 12:24:06 +08:00
elseif
1b857342ba Update README.md
Signed-off-by: elseif <elseif@live.cn>
2025-09-22 12:23:53 +08:00
elseif
4b4b257b4a Update README.md
Signed-off-by: elseif <elseif@live.cn>
2025-09-22 12:23:29 +08:00
elseif
597cbf30d8 Update README.md
Signed-off-by: elseif <elseif@live.cn>
2025-09-22 02:23:17 +08:00
elseif
6d7f3c0fd7 Update README.md
Signed-off-by: elseif <elseif@live.cn>
2025-09-22 02:22:46 +08:00
elseif
fc6fc897e1 Update README.md
Signed-off-by: elseif <elseif@live.cn>
2025-09-22 00:37:36 +08:00
elseif
0f45d580ba Update README.md
Signed-off-by: elseif <elseif@live.cn>
2025-09-22 00:34:33 +08:00
elseif
930a496ce4 Add files via upload
Signed-off-by: elseif <elseif@live.cn>
2025-09-21 22:26:54 +08:00
elseif
b7f321f748 Delete keygen/keygen_arm
Signed-off-by: elseif <elseif@live.cn>
2025-09-21 22:26:38 +08:00
elseif
f9662f6d23 Add files via upload
Signed-off-by: elseif <elseif@live.cn>
2025-09-21 22:26:25 +08:00
elseif
db5c0c3c8f Delete keygen/keygen_x86
Signed-off-by: elseif <elseif@live.cn>
2025-09-21 22:26:09 +08:00
elseif
93455ac7e7 Delete keygen/keygen_aarch64
Signed-off-by: elseif <elseif@live.cn>
2025-09-21 22:26:01 +08:00
elseif
29e25d9e8a Add files via upload
Signed-off-by: elseif <elseif@live.cn>
2025-09-21 22:23:40 +08:00
elseif
30a45fc829 Delete keygen/keygen_arm
Signed-off-by: elseif <elseif@live.cn>
2025-09-21 22:23:23 +08:00
elseif
9d91a8348d Add files via upload
Signed-off-by: elseif <elseif@live.cn>
2025-09-21 22:23:07 +08:00
elseif
66877c2071 Delete keygen/keygen_x86
Signed-off-by: elseif <elseif@live.cn>
2025-09-21 22:22:41 +08:00
elseif
671ad79933 Delete keygen/keygen_aarch64
Signed-off-by: elseif <elseif@live.cn>
2025-09-21 22:22:30 +08:00
elseif
61ba016da0 Update chr.sh
Signed-off-by: elseif <elseif@live.cn>
2025-09-19 23:28:40 +08:00
elseif
96d23defd3 Merge pull request #148 from FakeErrorX/main
Enhance UI with changelog modal and improved comments
2025-09-19 13:44:05 +08:00
ErrorX
5e80b52278 Merge branch 'main' into main
Signed-off-by: ErrorX <99178547+FakeErrorX@users.noreply.github.com>
2025-09-19 11:39:35 +06:00
ErrorX
54252e8645 Enhance UI with changelog modal and improved comments
Added a popup modal for viewing changelogs directly within the page, including loading and error states. Improved code readability with detailed comments, enhanced footer with banner-style social links, and clarified section headers and UI element purposes throughout the HTML and JavaScript. Also updated download links to use the changelog modal and improved GitHub proxy handling.
2025-09-19 11:32:05 +06:00
elseif
f03d0300d2 Update index.html
Signed-off-by: elseif <elseif@live.cn>
2025-09-19 13:07:29 +08:00
elseif
8281f0193f Update index.html
Signed-off-by: elseif <elseif@live.cn>
2025-09-19 13:02:02 +08:00
elseif
500c7b5748 Update index.html
Signed-off-by: elseif <elseif@live.cn>
2025-09-19 12:27:07 +08:00
elseif
e5b8288b35 Update index.html
Signed-off-by: elseif <elseif@live.cn>
2025-09-19 12:23:54 +08:00
elseif
fe493a8f0f Update index.html
Signed-off-by: elseif <elseif@live.cn>
2025-09-19 12:07:24 +08:00
elseif
e8bd998953 Update index.html
Signed-off-by: elseif <elseif@live.cn>
2025-09-19 12:05:41 +08:00
elseif
9ad4028007 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-09-19 10:59:11 +08:00
elseif
f55fba6699 Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-09-19 01:03:56 +08:00
elseif
e2debac366 Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-09-19 00:59:40 +08:00
elseif
7fe82f7498 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-09-19 00:32:10 +08:00
elseif
e7a08895f5 Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2025-09-18 23:35:16 +08:00
elseif
b436141665 Update index.html
Signed-off-by: elseif <elseif@live.cn>
2025-09-18 23:29:20 +08:00
elseif
86e2727c56 Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2025-09-18 23:15:40 +08:00
elseif
96670cbe60 Update npk.py
Signed-off-by: elseif <elseif@live.cn>
2025-09-18 23:04:30 +08:00
elseif
f91f8e15d0 Merge pull request #145 from FakeErrorX/main
Redesign index.html
2025-09-18 16:49:01 +08:00
elseif
c4dd46205b Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2025-09-18 16:35:11 +08:00
elseif
4f9d2133fd Update npk.py
Signed-off-by: elseif <elseif@live.cn>
2025-09-18 16:33:57 +08:00
ErrorX
b6721ffd7d Redesign index.html
Replaces legacy CSS and table-based layout with modernizes the UI with responsive cards, details/summary accordions, and improved theme/language switching. Adds dynamic loading, new download tables, and enhanced accessibility. Removes old inline styles and scripts, streamlining the code for maintainability and better user experience.
2025-09-16 15:08:43 +06:00
elseif
6cbdbffbcb Update chr.sh
Signed-off-by: elseif <elseif@live.cn>
2025-09-13 03:43:55 +08:00
elseif
6d27075389 Update index.html
Signed-off-by: elseif <elseif@live.cn>
2025-09-13 03:39:43 +08:00
10 changed files with 1008 additions and 990 deletions

View File

@@ -212,8 +212,8 @@ jobs:
fi
sudo cp -f system-$LATEST_VERSION.npk ./new_iso/
sudo -E python3 patch.py kernel ./new_iso/isolinux/initrd.rgz
# sudo -E python3 npk.py create ./new_iso/gps-$LATEST_VERSION.npk ./option-$LATEST_VERSION.npk option ./option.sfs -desc="busybox"
# sudo cp option-$LATEST_VERSION.npk ./new_iso/
sudo -E python3 npk.py create ./new_iso/gps-$LATEST_VERSION.npk ./option-$LATEST_VERSION.npk option ./option.sfs -desc="busybox"
sudo cp option-$LATEST_VERSION.npk ./new_iso/
sudo mkisofs -o mikrotik-$LATEST_VERSION.iso \
-V "MikroTik $LATEST_VERSION" \
-sysid "" -preparer "MiKroTiK" \
@@ -291,8 +291,10 @@ jobs:
sudo cp ./all_packages/dude-$LATEST_VERSION.npk ./chr/var/pdb/dude/image
sudo -E python3 patch.py npk ./chr/var/pdb/routeros-x86/image
sudo cp ./chr/var/pdb/routeros-x86/image ./all_packages/routeros-x86-$LATEST_VERSION.npk
# sudo mkdir -p ./chr/var/pdb/option
# sudo cp ./all_packages/option-$LATEST_VERSION.npk ./chr/var/pdb/option/image
sudo mkdir -p ./chr/var/pdb/option
sudo cp ./all_packages/option-$LATEST_VERSION.npk ./chr/var/pdb/option/image
sudo mkdir -p ./chr/rw/disk
echo -e '#!/bin/sh\n# This script will be executed *before* RouterOS *loader* start.\n# You can put your own initialization stuff in here\n' | sudo tee ./chr/rw/disk/rc.local
sudo umount ./chr
sudo qemu-nbd -d /dev/nbd0
sudo rm -rf ./chr

View File

@@ -246,6 +246,16 @@ jobs:
sudo -E python3 npk.py sign "$file" "$file"
done
fi
if [ "$LATEST_VERSION" = "7.12.1" ]; then
URL="https://download.mikrotik.com/routeros/$LATEST_VERSION/routeros-${{ matrix.arch }}-$LATEST_VERSION.npk"
sudo wget -nv -O "routeros-${{ matrix.arch }}-$LATEST_VERSION.npk" "$URL"
sudo -E python3 patch.py npk routeros-${{ matrix.arch }}-$LATEST_VERSION.npk
sudo mv "routeros-${{ matrix.arch }}-$LATEST_VERSION.npk" ./new_iso
URL="https://download.mikrotik.com/routeros/$LATEST_VERSION/system-$LATEST_VERSION.npk"
sudo wget -nv -O "system-$LATEST_VERSION.npk" "$URL"
sudo -E python3 patch.py npk system-$LATEST_VERSION.npk
sudo mv "system-$LATEST_VERSION.npk" ./new_iso
fi
sudo cp -f routeros-$LATEST_VERSION$ARCH.npk ./new_iso/
sudo -E python3 npk.py create ./new_iso/gps-$LATEST_VERSION$ARCH.npk ./option-$LATEST_VERSION$ARCH.npk option ./option.sfs -desc="busybox"
sudo cp option-$LATEST_VERSION$ARCH.npk ./new_iso/
@@ -322,7 +332,7 @@ jobs:
</References>
<DiskSection>
<Info>Virtual disk information</Info>
<Disk ovf:capacity="{CAPACITY_MB}" ovf:capacityAllocationUnits="byte * 2^20" ovf:diskId="vmdisk1" ovf:fileRef="file1" ovf:format="http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized" ovf:populatedSize="{POPULATED_SIZE}"/>
<Disk ovf:capacity="{CAPACITY_MB}" ovf:capacityAllocationUnits="byte * 2^20" ovf:diskId="vmdisk1" ovf:fileRef="file1" ovf:format="http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized"/>
</DiskSection>
<NetworkSection>
<Info>The list of logical networks</Info>

View File

@@ -1,6 +1,17 @@
[![Patch Mikrotik RouterOS 6.x](https://github.com/elseif/MikroTikPatch/actions/workflows/mikrotik_patch_6.yml/badge.svg)](https://github.com/elseif/MikroTikPatch/actions/workflows/mikrotik_patch_6.yml)
[![Patch Mikrotik RouterOS 7.x](https://github.com/elseif/MikroTikPatch/actions/workflows/mikrotik_patch_7.yml/badge.svg)](https://github.com/elseif/MikroTikPatch/actions/workflows/mikrotik_patch_7.yml)
### 感谢赞助
[DartNode(aff)](https://dartnode.com?aff=SnazzyLobster067) | [ZMTO(aff)](https://console.zmto.com/?affid=1588) | [Vultr(aff)](https://www.vultr.com/?ref=9807160-9J)
### 感谢捐赠
ETH/BSC/MATIC(USDT)0x7d5ade1bb74f170411ba4a9a6e8752d7b431b455
TRX(USDT): TJ1Spmytu9CFhDg4QSo3cmWSrBKjNXuUYP
捐赠后请将交易号或链接通过tg或email发给我记录。
# MikroTik RouterOS Patch [[English](README_EN.md)]
[![License: WTFPL](https://img.shields.io/badge/License-WTFPL-brightgreen.svg)](./LICENSE)
[![CoC:WTFCoC](https://img.shields.io/badge/CoC-WTFCoC-brightgreen.svg)](./CODE_OF_CONDUCT.md)
@@ -60,8 +71,9 @@ graph TD
## 所有的修补操作都自动运行在[Github Action](https://github.com/elseif/MikroTikPatch/blob/main/.github/workflows/)。
### 感谢赞助
[ZMTO](https://console.zmto.com)

325
chr.sh
View File

@@ -1,82 +1,263 @@
#!/bin/bash
set -e
LATEST_VERSION="${1:-7.19.4}"
echo "VERSION: $LATEST_VERSION"
ARCH=$(uname -m)
case $ARCH in
x86_64|i386|i486|i586|i686)
echo "ARCH: $ARCH"
if [ -d /sys/firmware/efi ]; then
echo "BOOT MODE: UEFI"
IMG_URL="https://github.com/elseif/MikroTikPatch/releases/download/$LATEST_VERSION/chr-$LATEST_VERSION.img.zip"
else
echo "BOOT MODE: BIOS/MBR"
IMG_URL="https://github.com/elseif/MikroTikPatch/releases/download/$LATEST_VERSION/chr-$LATEST_VERSION-legacy-bios.img.zip"
fi
;;
aarch64)
echo "ARCH: $ARCH"
IMG_URL="https://github.com/elseif/MikroTikPatch/releases/download/$LATEST_VERSION-arm64/chr-$LATEST_VERSION-arm64.img.zip"
;;
*)
echo "Unsupported architecture: $ARCH"
exit 1
;;
esac
STORAGE=$(lsblk -d -n -o NAME,TYPE | awk '$2=="disk"{print $1; exit}')
echo "STORAGE: $STORAGE"
ETH=$(ip route show default | grep '^default' | sed -n 's/.* dev \([^\ ]*\) .*/\1/p')
echo "ETH: $ETH"
ADDRESS=$(ip addr show $ETH | grep global | cut -d' ' -f 6 | head -n 1)
echo "ADDRESS: $ADDRESS"
GATEWAY=$(ip route list | grep default | cut -d' ' -f 3)
echo "GATEWAY: $GATEWAY"
DNS=$(grep '^nameserver' /etc/resolv.conf | awk '{print $2}' | head -n 1)
[ -z "$DNS" ] && DNS="8.8.8.8"
echo "DNS: $DNS"
echo "FILE: $(basename $IMG_URL)"
if command -v wget >/dev/null 2>&1; then
wget --no-check-certificate -O /tmp/chr.img.zip "$IMG_URL" || { echo "Download failed!"; exit 1; }
elif command -v curl >/dev/null 2>&1; then
curl -L --insecure -o /tmp/chr.img.zip "$IMG_URL" || { echo "Download failed!"; exit 1; }
else
echo "Neither wget nor curl is installed. Cannot download $url"
exit 1
fi
cd /tmp
gunzip -c chr.img.zip > chr.img
RANDOM_PASS=$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c 8)
if LOOP=$(losetup -Pf --show chr.img 2>/dev/null); then
sleep 3
MNT=/tmp/chr
mkdir -p $MNT
if mount ${LOOP}p2 $MNT 2>/dev/null; then
cat <<EOF | tee $MNT/rw/autorun.scr
set_language() {
local current_lang=${LANG:-C}
current_lang=${current_lang%%.*}
if [[ "$current_lang" == "zh_CN" ]]; then
MSG_SYSTEM_INFO="系统信息:"
MSG_ARCH="CPU架构:"
MSG_BOOTMODE="引导模式:"
MSG_STORAGE_DEVICE="存储设备:"
MSG_ETH_DEVICE="网络设备:"
MSG_ADDRESS="IP地址:"
MSG_GATEWAY="网关:"
MSG_DNS="DNS服务器:"
MSG_SELECT_VERSION="请选择您要安装的版本:"
MSG_STABLE="稳定版 (v7)"
MSG_TEST="测试版 (v7)"
MSG_LTS="长期支持版 (v6)"
MSG_STABLE6="稳定版 (v6)"
MSG_PLEASE_CHOOSE="请选择一个选项:"
MSG_UNSUPPORTED_ARCH="错误: 不支持的架构: "
MSG_INVALID_OPTION="错误: 无效选项"
MSG_ARM64_NOT_SUPPORT_V6="ARM64架构暂不支持安装v6版本"
MSG_SELECTED_VERSION="已选择版本:"
MSG_FILE_DOWNLOAD="下载文件: "
MSG_DOWNLOAD_ERROR="错误: wget 或 curl 都未安装,无法下载文件。"
MSG_EXTRACT_ERROR="错误: unzip 或 gunzip 都未安装,无法解压文件。"
MSG_DOWNLOAD_FAILED="错误: 下载失败!"
MSG_OPERATION_ABORTED="错误: 操作已中止。"
MSG_WARNING="警告:/dev/%s 上的数据将会丢失!"
MSG_REBOOTING="好的,正在重启..."
MSG_ADMIN_PASSWORD="管理员密码:"
MSG_MANUAL_PASS_CHOICE="是否手动输入密码?(y/N): "
MSG_ENTER_NEW_PASS="请输入新密码: "
MSG_PASS_EMPTY="密码不能为空,请重新输入。"
MSG_ERROR_MOUNT="错误: 挂载分区失败"
MSG_ERROR_LOOP="错误: 设置 loop 设备失败"
MSG_AUTO_RUN_FILE_CREATED="autorun.scr 文件已创建。"
MSG_CONFIRM_CONTINUE="您是否确定继续? [Y/n]:"
else
MSG_SYSTEM_INFO="SYSTEM INFO:"
MSG_ARCH="ARCH:"
MSG_BOOTMODE="BOOT MODE:"
MSG_STORAGE_DEVICE="STORAGE:"
MSG_ETH_DEVICE="ETH:"
MSG_ADDRESS="ADDRESS:"
MSG_GATEWAY="GATEWAY:"
MSG_DNS="DNS:"
MSG_SELECT_VERSION="Select the version you want to install:"
MSG_STABLE="stable (v7)"
MSG_TEST="testing (v7)"
MSG_LTS="long-term (v6)"
MSG_STABLE6="stable (v6)"
MSG_PLEASE_CHOOSE="Please choose an option:"
MSG_UNSUPPORTED_ARCH="Error: Unsupported architecture: "
MSG_INVALID_OPTION="Error: Invalid option!"
MSG_ARM64_NOT_SUPPORT_V6="arm64 does not support v6 version for now."
MSG_SELECTED_VERSION="Selected version:"
MSG_FILE_DOWNLOAD="Download file: "
MSG_DOWNLOAD_ERROR="Error: No wget nor curl is installed. Cannot download."
MSG_EXTRACT_ERROR="Error: No unzip nor gunzip is installed. Cannot uncompress."
MSG_DOWNLOAD_FAILED="Error: Download failed!"
MSG_OPERATION_ABORTED="Error: Operation aborted."
MSG_WARNING="Warn: All data on /dev/%s will be lost!"
MSG_REBOOTING="Ok, rebooting..."
MSG_ADMIN_PASSWORD="admin password:"
MSG_MANUAL_PASS_CHOICE="Do you want to enter a password manually? (y/N): "
MSG_ENTER_NEW_PASS="Enter new password: "
MSG_PASS_EMPTY="Password cannot be empty, please try again."
MSG_ERROR_MOUNT="Error: Failed to mount partition"
MSG_ERROR_LOOP="Error: Failed to setup loop device"
MSG_AUTO_RUN_FILE_CREATED="autorun.scr file created."
MSG_CONFIRM_CONTINUE="Do you want to continue? [Y/n]:"
fi
}
show_system_info() {
ARCH=$(uname -m)
BOOT_MODE=$( [ -d "/sys/firmware/efi" ] && echo "UEFI" || echo "BIOS" )
STORAGE=$(lsblk -d -n -o NAME,TYPE | awk '$2=="disk"{print $1; exit}')
ETH=$(ip route show default | grep '^default' | sed -n 's/.* dev \([^\ ]*\) .*/\1/p')
ADDRESS=$(ip addr show $ETH | grep global | cut -d' ' -f 6 | head -n 1)
GATEWAY=$(ip route list | grep default | cut -d' ' -f 3)
DNS=$(grep '^nameserver' /etc/resolv.conf | awk '{print $2}' | head -n 1)
[ -z "$DNS" ] && DNS="8.8.8.8"
echo "$MSG_SYSTEM_INFO"
echo "$MSG_ARCH $ARCH"
echo "$MSG_BOOTMODE $BOOT_MODE"
echo "$MSG_STORAGE_DEVICE $STORAGE"
echo "$MSG_ETH_DEVICE $ETH"
echo "$MSG_ADDRESS $ADDRESS"
echo "$MSG_GATEWAY $GATEWAY"
echo "$MSG_DNS $DNS"
}
select_version() {
if [[ -n "$VERSION" ]]; then
if [[ "$VERSION" == 7.* ]]; then
V7=1
elif [[ "$VERSION" == 6.* ]]; then
V7=0
else
echo "Error: Unsupported version $VERSION"
exit 1
fi
echo "$MSG_SELECTED_VERSION $VERSION"
return
fi
while true; do
case $ARCH in
x86_64|i386|i486|i586|i686)
echo "$MSG_SELECT_VERSION"
echo "1. $MSG_STABLE"
echo "2. $MSG_TEST"
echo "3. $MSG_LTS"
echo "4. $MSG_STABLE6"
read -p "$MSG_PLEASE_CHOOSE [1-4]" version_choice
;;
aarch64)
echo "$MSG_SELECT_VERSION"
echo "1. $MSG_STABLE"
echo "2. $MSG_TEST"
read -p "$MSG_PLEASE_CHOOSE [1-2]" version_choice
;;
*)
echo "$MSG_UNSUPPORTED_ARCH $ARCH"
exit 1
;;
esac
case $version_choice in
1) VERSION=$(curl -s "https://upgrade.mikrotik.ltd/routeros/NEWESTa7.stable" | cut -d' ' -f1); V7=1 ;;
2) VERSION=$(curl -s "https://upgrade.mikrotik.ltd/routeros/NEWESTa7.testing" | cut -d' ' -f1); V7=1 ;;
3)
if [[ "$ARCH" == "aarch64" ]]; then
echo "$MSG_ARM64_NOT_SUPPORT_V6"
continue
fi
VERSION=$(curl -s "https://upgrade.mikrotik.ltd/routeros/NEWEST6.long-term" | cut -d' ' -f1)
V7=0
;;
4)
if [[ "$ARCH" == "aarch64" ]]; then
echo "$MSG_ARM64_NOT_SUPPORT_V6"
continue
fi
VERSION=$(curl -s "https://upgrade.mikrotik.ltd/routeros/NEWEST6.stable" | cut -d' ' -f1)
V7=0
;;
*)
echo "$MSG_INVALID_OPTION"
continue
;;
esac
echo "$MSG_SELECTED_VERSION $VERSION"
break
done
}
download_image(){
case $ARCH in
x86_64|i386|i486|i586|i686)
if [[ $V7 == 1 && $BOOT_MODE == "BIOS" ]]; then
IMG_URL="https://github.com/elseif/MikroTikPatch/releases/download/$VERSION/chr-$VERSION-legacy-bios.img.zip"
else
IMG_URL="https://github.com/elseif/MikroTikPatch/releases/download/$VERSION/chr-$VERSION.img.zip"
fi
;;
aarch64)
IMG_URL="https://github.com/elseif/MikroTikPatch/releases/download/$VERSION-arm64/chr-$VERSION-arm64.img.zip"
;;
*)
echo "$MSG_UNSUPPORTED_ARCH"
exit 1
;;
esac
echo "$MSG_FILE_DOWNLOAD $(basename "$IMG_URL")"
if command -v curl >/dev/null 2>&1; then
curl -L -# -o /tmp/chr.img.zip "$IMG_URL" || { echo "$MSG_DOWNLOAD_FAILED"; exit 1; }
elif command -v wget >/dev/null 2>&1; then
wget -nv -O /tmp/chr.img.zip "$IMG_URL" || { echo "$MSG_DOWNLOAD_FAILED"; exit 1; }
else
echo "$MSG_DOWNLOAD_ERROR $IMG_URL"
exit 1
fi
cd /tmp
if command -v unzip >/dev/null 2>&1; then
unzip -p "chr.img.zip" > chr.img
elif command -v gunzip >/dev/null 2>&1; then
gunzip -c chr.img.zip > chr.img
else
echo "$MSG_EXTRACT_ERROR"
exit 1
fi
}
create_autorun() {
if LOOP=$(losetup -Pf --show chr.img 2>/dev/null); then
sleep 1
MNT=/tmp/chr
mkdir -p $MNT
PARTITION=$([ "$V7" == 1 ] && echo "p2" || echo "p1")
if mount "${LOOP}${PARTITION}" "$MNT" 2>/dev/null; then
RANDOM_ADMIN_PASS=$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c 16)
echo -e "$MSG_ADMIN_PASSWORD \e[31m$RANDOM_ADMIN_PASS\e[0m"
read -p "$MSG_MANUAL_PASS_CHOICE" input_pass_choice < /dev/tty
input_pass_choice=${input_pass_choice:-N}
if [[ "$input_pass_choice" =~ ^[Yy]$ ]]; then
while true; do
read -p "$MSG_ENTER_NEW_PASS" user_pass
if [[ -n "$user_pass" ]]; then
RANDOM_ADMIN_PASS="$user_pass"
echo -e "$MSG_ADMIN_PASSWORD \e[31m$RANDOM_ADMIN_PASS\e[0m"
break
else
echo "$MSG_PASS_EMPTY"
fi
done
fi
cat <<EOF > "$MNT/rw/autorun.scr"
/user set admin password="$RANDOM_ADMIN_PASS"
/ip dns set servers=$DNS
/ip address add address=$ADDRESS interface=ether1
/ip route add gateway=$GATEWAY
/ip dns set servers=$DNS
/user set admin password="$RANDOM_PASS"
EOF
echo "autorun.scr file created."
echo -e "admin password: \e[31m$RANDOM_PASS\e[0m"
umount $MNT
echo "$MSG_AUTO_RUN_FILE_CREATED"
umount $MNT
losetup -d "$LOOP"
else
losetup -d "$LOOP"
echo "$MSG_ERROR_MOUNT $PARTITION"
exit 1
fi
else
echo "Failed to mount partition 2, skipping autorun.scr creation."
echo "$MSG_ERROR_LOOP"
exit 1
fi
losetup -d $LOOP
fi
}
echo "WARNING: All data on /dev/$STORAGE will be lost!"
read -p "Do you want to continue? [Y/n]: " confirm < /dev/tty
confirm=${confirm:-Y}
if [[ "$confirm" =~ ^[Nn]$ ]]; then
echo "Operation aborted."
exit 1
fi
dd if=chr.img of=/dev/$STORAGE bs=4M conv=fsync
echo "Ok, rebooting..."
echo 1 > /proc/sys/kernel/sysrq 2>/dev/null || true
echo b > /proc/sysrq-trigger 2>/dev/null || true
reboot -f
write_and_reboot() {
printf "$MSG_WARNING\n" "$STORAGE"
read -p "$MSG_CONFIRM_CONTINUE" confirm < /dev/tty
confirm=${confirm:-Y}
if [[ "$confirm" =~ ^[Nn]$ ]]; then
echo "$MSG_OPERATION_ABORTED"
exit 1
fi
dd if=chr.img of=/dev/$STORAGE bs=4M conv=fsync
echo "$MSG_REBOOTING"
echo 1 > /proc/sys/kernel/sysrq 2>/dev/null || true
echo b > /proc/sysrq-trigger 2>/dev/null || true
reboot -f
}
set_language
show_system_info
select_version
download_image
create_autorun
write_and_reboot
exit 0

1578
index.html

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

51
npk.py
View File

@@ -207,10 +207,9 @@ class NovaPackage(Package):
self._parts.append(NpkPartItem(NpkPartID(part_id),NpkInfo.unserialize_from(part_data)))
else:
self._parts.append(NpkPartItem(NpkPartID(part_id),part_data))
def set_null_block(self):
def rebuild_squashfs(data):
if len(part.data) < 4 or part.data[:4] != b'hsqs':
return part.data
with open('squashfs.sfs', 'wb') as f:
f.write(data)
os.system('unsquashfs -d squashfs-root squashfs.sfs')
@@ -219,19 +218,20 @@ class NovaPackage(Package):
os.system('rm -rf squashfs-root')
with open('squashfs.sfs', 'rb') as f:
return f.read()
if len(self._packages) > 0:
def get_size(package,size):
for part in package._parts:
size += 6
size += len(part.data)
return size
def set_null(package,offset):
has_squashfs = False
for package in self._packages:
for part in package._parts:
if part.id == NpkPartID.SQUASHFS:
part.data = rebuild_squashfs(part.data)
has_squashfs = True
if not has_squashfs:
return
for package in self._packages:
count = 8
for part in package._parts:
if part.id == NpkPartID.SQUASHFS and len(part.data) >= 4 and part.data[:4] in [b'hsqs',b'sqsh']:
part.data = rebuild_squashfs(part.data)
has_squashfs = True
if has_squashfs:
count = offset
for part in package._parts:
count += 6
if part.id == NpkPartID.NULL_BLOCK:
@@ -241,23 +241,12 @@ class NovaPackage(Package):
pad_len = (4096 - (count % 4096)) % 4096
package[NpkPartID.NULL_BLOCK].data = b'\x00' * pad_len
else:
has_squashfs = False
for part in self._parts:
if part.id == NpkPartID.SQUASHFS:
part.data = rebuild_squashfs(part.data)
has_squashfs = True
if not has_squashfs:
return
count = 8
for part in self._parts:
count += 6
if part.id == NpkPartID.NULL_BLOCK:
break
count += len(part.data)
count += 6
pad_len = (4096 - (count % 4096)) % 4096
self[NpkPartID.NULL_BLOCK].data = b'\x00' * pad_len
set_null(self,8)
offset = get_size(self,8)
for package in self._packages:
set_null(package,offset)
offset += get_size(package,0)
def get_digest(self,hash_fnc,package:Package=None)->bytes:
parts = package._parts if package else self._parts
for part in parts:

View File

@@ -328,6 +328,12 @@ def patch_squashfs(path,key_dict):
if _file =='loader':
patch_loader(file)
continue
if _file =='BOOTX64.EFI':
print(f'patch {file} ...')
data = open(file,'rb').read()
data = patch_kernel(data,key_dict)
open(file,'wb').write(data)
continue
data = open(file,'rb').read()
for old_public_key,new_public_key in key_dict.items():
_data = replace_key(old_public_key,new_public_key,data,file)