From f7d2e6e45afeff068a6b26e7cd5c1ac8b3e2b5a4 Mon Sep 17 00:00:00 2001 From: 6ccg <44950572+6ccg@users.noreply.github.com> Date: Tue, 6 Oct 2026 03:28:27 +0800 Subject: [PATCH] Add opt-in Xiaomi HwCountry GLOBAL override --- README.md | 4 +- README_zh.md | 4 +- submodules/patcher/Makefile | 6 + .../patcher/include/patchs/xiaomi/hwcountry.h | 9 + submodules/patcher/src/patch_abl.c | 14 +- submodules/patcher/src/patchs/core.c | 2 +- .../patcher/src/patchs/xiaomi/hwcountry.c | 198 ++++++++++++++++++ submodules/patcher/tests/test_hwcountry.c | 106 ++++++++++ targets/toolkit_android/resources/build.sh | 2 +- targets/toolkit_linux/resources/build.sh | 2 +- targets/toolkit_windows/resources/build.bat | 6 +- 11 files changed, 342 insertions(+), 11 deletions(-) create mode 100644 submodules/patcher/include/patchs/xiaomi/hwcountry.h create mode 100644 submodules/patcher/src/patchs/xiaomi/hwcountry.c create mode 100644 submodules/patcher/tests/test_hwcountry.c diff --git a/README.md b/README.md index 365aeab37..907f94c40 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,9 @@ If you downloaded the `target_toolkit_linux` or `target_toolkit_windows` zip fil 3. **Linux:** Run `bash build.sh`. **Windows:** Run `build.bat`. 4. The script extracts and cracks the ABL, outputting `ABL.efi` (fake re-lock) and `ABL_original.efi` (original). `BDS.efi` is bundled. Check `patch_log.txt` - if it says "Warning: Failed to patch ABL GBL", the ABL lacks the vulnerability and the `abl` partition must be downgraded to an older ABL with it. -Then complete the install manually (see the [Wiki](https://github.com/superturtlee/gbl_root_canoe/wiki) for full steps): copy `ABL.efi` into `/mnt/vendor/persist/efisp/`, create `BOOTENTRIES`, `sync`, and flash `BDS.efi` to `efisp` (`dd if=BDS.efi of=/dev/block/by-name/efisp bs=4M`). +For Xiaomi/HyperOS region override, explicitly run `bash build.sh --hwcountry-global` (Linux), `build.bat --hwcountry-global` (Windows), or `sh build.sh --hwcountry-global` (Android toolkit). This redirects the supported ABL's HwCountry getvar and display references to `GLOBAL`, adapting the feature from [HyperCanoe](https://github.com/StevenWin818/GBL_Root_HyperCanoe). The default build keeps the hardware country unchanged. Unsupported or ambiguous layouts and unavailable PE tail padding fail without producing a patched file. The patcher also accepts `patch_abl ABL_original.efi boot.efi --hwcountry-global` directly; the module's automatic installer does not enable this option. + +Then complete the install manually (see the [Wiki](https://github.com/superturtlee/gbl_root_canoe/wiki) for full steps): copy the generated `efisp/boot.efi` into `/mnt/vendor/persist/efisp/`, use the toolkit's `BOOTENTRIES`, `sync`, and flash `BDS.efi` to `efisp` (`dd if=BDS.efi of=/dev/block/by-name/efisp bs=4M`). `boot.efi` is a chain-loaded EFI application: do not flash it to the `abl` or `efisp` partition. Static patch validation does not establish that a device will boot; the installed ABL/BDS chain must be compatible. ### 3. OTA Upgrade Before rebooting for an OTA update, use the module WebUI to flash and retain the old ABL version. "Update efisp" is enabled by default; for a major version upgrade keep it on, otherwise the device may get stuck on the first boot screen. diff --git a/README_zh.md b/README_zh.md index b05bf76f0..2bbb3ca6e 100644 --- a/README_zh.md +++ b/README_zh.md @@ -66,7 +66,9 @@ 3. **Linux 平台:** 开启终端执行 `bash build.sh`。**Windows 平台:** 双击运行 `build.bat`。 4. 脚本会提取并破解 ABL,输出 `ABL.efi`(假回锁)和 `ABL_original.efi`(原版),`BDS.efi` 已附带。请查看 `patch_log.txt`,若显示 "Warning: Failed to patch ABL GBL",则该 ABL 没有漏洞,需将 `abl` 分区降级为带有 GBL 漏洞的旧版本 ABL。 -随后手动完成安装(完整步骤见 [Wiki](https://github.com/superturtlee/gbl_root_canoe/wiki)):将 `ABL.efi` 复制到 `/mnt/vendor/persist/efisp/`,创建 `BOOTENTRIES`,`sync`,再将 `BDS.efi` 刷入 `efisp`(`dd if=BDS.efi of=/dev/block/by-name/efisp bs=4M`)。 +小米 / HyperOS 跨区功能需显式启用:Linux 执行 `bash build.sh --hwcountry-global`,Windows 执行 `build.bat --hwcountry-global`,Android 工具包执行 `sh build.sh --hwcountry-global`。此功能移植自 [HyperCanoe](https://github.com/StevenWin818/GBL_Root_HyperCanoe),将支持的 ABL 中 HwCountry 的 getvar 和显示指针重定向为 `GLOBAL`;默认不修改硬件地区。布局不支持、引用不唯一或没有可用的 PE 段尾填充时会失败,不生成修补文件。也可直接执行 `patch_abl ABL_original.efi boot.efi --hwcountry-global`;模块的自动安装流程不启用此选项。 + +随后手动完成安装(完整步骤见 [Wiki](https://github.com/superturtlee/gbl_root_canoe/wiki)):将生成的 `efisp/boot.efi` 复制到 `/mnt/vendor/persist/efisp/`,使用工具包的 `BOOTENTRIES`,`sync`,再将 `BDS.efi` 刷入 `efisp`(`dd if=BDS.efi of=/dev/block/by-name/efisp bs=4M`)。`boot.efi` 是通过启动链加载的 EFI 应用,不能刷到 `abl` 或 `efisp` 分区。静态补丁校验不能证明实机一定能启动,现有 ABL / BDS 启动链还需匹配。 ### 3. OTA 升级 重启进行 OTA 更新前,使用模块 WebUI 刷写以保留旧版本 ABL。“更新 efisp”默认开启;跨版本升级时请保持开启,否则可能卡一屏。 diff --git a/submodules/patcher/Makefile b/submodules/patcher/Makefile index 7ce32274f..0c5c07124 100644 --- a/submodules/patcher/Makefile +++ b/submodules/patcher/Makefile @@ -15,3 +15,9 @@ build_android: build_windows: mkdir -p build x86_64-w64-mingw32-gcc $(CFLAGS) -o build/patch_abl.exe $(SRCS) + +.PHONY: test +test: + mkdir -p build + gcc $(CFLAGS) -o build/test_hwcountry tests/test_hwcountry.c src/patchs/xiaomi/hwcountry.c src/arm64_inst/arm64_inst_decoder.c src/arm64_inst/utils.c + ./build/test_hwcountry diff --git a/submodules/patcher/include/patchs/xiaomi/hwcountry.h b/submodules/patcher/include/patchs/xiaomi/hwcountry.h new file mode 100644 index 000000000..d9dc29bb7 --- /dev/null +++ b/submodules/patcher/include/patchs/xiaomi/hwcountry.h @@ -0,0 +1,9 @@ +#ifndef PATCHS_XIAOMI_HWCOUNTRY_H +#define PATCHS_XIAOMI_HWCOUNTRY_H + +#include + +/* Returns 0 on success, -1 if the supported HwCountry layout is absent. */ +int32_t patch_hwcountry_global(char* buffer, int32_t size); + +#endif diff --git a/submodules/patcher/src/patch_abl.c b/submodules/patcher/src/patch_abl.c index 48e92993a..5b8a64077 100644 --- a/submodules/patcher/src/patch_abl.c +++ b/submodules/patcher/src/patch_abl.c @@ -1,7 +1,9 @@ #include "patchs/core.h" +#include "patchs/xiaomi/hwcountry.h" //FILE #include #include +#include /* ==================== main ==================== */ int32_t read_file(const char* filename, char** data, int32_t* size) { FILE* file = fopen(filename, "rb"); @@ -18,8 +20,9 @@ int32_t read_file(const char* filename, char** data, int32_t* size) { return 0; } int32_t main(int32_t argc, char* argv[]) { - if (argc != 3) { - printf("Usage: %s \n", argv[0]); + bool hwcountry_global = argc == 4 && strcmp(argv[3], "--hwcountry-global") == 0; + if (argc != 3 && !hwcountry_global) { + printf("Usage: %s [--hwcountry-global]\n", argv[0]); return EXIT_FAILURE; } char* data = NULL; @@ -28,6 +31,11 @@ int32_t main(int32_t argc, char* argv[]) { printf("Failed to read file: %s\n", argv[1]); return EXIT_FAILURE; } + if (hwcountry_global && patch_hwcountry_global(data, size) != 0) { + printf("Error: Failed to patch HwCountry -> GLOBAL\n"); + free(data); + return EXIT_FAILURE; + } if (!PatchBuffer(data,size)) { printf("Patching failed\n"); @@ -50,4 +58,4 @@ int32_t main(int32_t argc, char* argv[]) { free(data); printf("Saved to %s\n", argv[2]); return EXIT_SUCCESS; -} \ No newline at end of file +} diff --git a/submodules/patcher/src/patchs/core.c b/submodules/patcher/src/patchs/core.c index fb8fe33bd..a70bb7d05 100644 --- a/submodules/patcher/src/patchs/core.c +++ b/submodules/patcher/src/patchs/core.c @@ -96,7 +96,7 @@ int32_t source_callback(char* buffer, int32_t size, int32_t now_offset, int8_t c #endif #ifndef DISABLE_PATCH_5 int32_t fwd = track_forward_patch_strb(buffer, size, now_offset, current_target, anchor_offset); - if (fwd <= 0) { + if (fwd != SUCCESS) { printf("Warning: sink STRB not found after anchor 0x%X\n", anchor_offset); return -1; } diff --git a/submodules/patcher/src/patchs/xiaomi/hwcountry.c b/submodules/patcher/src/patchs/xiaomi/hwcountry.c new file mode 100644 index 000000000..7e17d5d71 --- /dev/null +++ b/submodules/patcher/src/patchs/xiaomi/hwcountry.c @@ -0,0 +1,198 @@ +/* HwCountry redirection adapted from StevenWin818/GBL_Root_HyperCanoe. */ +#include "arm64_inst/utils.h" +#include "patchs/xiaomi/hwcountry.h" + +static int32_t find_cstring(const char* buffer, int32_t size, const char* needle) { + int32_t length = (int32_t)strlen(needle) + 1; + for (int32_t i = 0; i <= size - length; ++i) + if (memcmp(buffer + i, needle, length) == 0) return i; + return -1; +} + +static int32_t find_reference(const char* buffer, int32_t size, int64_t target) { + int32_t result = -1; + for (int32_t i = 0; i <= size - 8; i += 4) { + if (calc_adrl_file_offset(buffer, i, 0) != target) continue; + if (result >= 0) { + printf("HwCountry: ambiguous ADRP+ADD references to 0x%llX\n", + (unsigned long long)target); + return -1; + } + result = i; + } + return result; +} + +static uint16_t read_u16(const char* buffer, int32_t off) { + uint16_t value; + memcpy(&value, buffer + off, sizeof(value)); + return value; +} + +static bool in_range(int64_t target, int32_t start, int32_t length) { + return target >= start && target < (int64_t)start + length; +} + +static bool slack_is_referenced(const char* buffer, int32_t size, + int32_t start, int32_t length) { + for (int32_t i = 0; i <= size - 8; i += 4) { + if (in_range(calc_adrl_file_offset(buffer, i, 0), start, length)) return true; + uint32_t raw = read_instr(buffer, i); + if ((raw & 0x9F000000u) == 0x10000000u) { /* ADR */ + int32_t imm = ((raw >> 29) & 3) | (((raw >> 5) & 0x7FFFF) << 2); + if (imm & 0x100000) imm -= 0x200000; + if (in_range((int64_t)i + imm, start, length)) return true; + } + if ((raw & 0x3B000000u) == 0x18000000u) { /* LDR literal */ + if (in_range((int64_t)i + decode_imm19(raw), start, length)) return true; + } + if ((raw & 0x7E000000u) == 0x36000000u) { /* TBZ/TBNZ */ + int32_t imm = (raw >> 5) & 0x3FFF; + if (imm & 0x2000) imm -= 0x4000; + if (in_range((int64_t)i + imm * 4, start, length)) return true; + } + DecodedInst d = decode_at(buffer, i); + int64_t target; + if (get_JUMP_target(&d, i, &target) && in_range(target, start, length)) return true; + } + return false; +} + +static int32_t find_slack(const char* buffer, int32_t size, int32_t need) { + /* Only use mapped, readable .text tail padding in a flat ARM64 PE. */ + if (size < 64 || memcmp(buffer, "MZ", 2) != 0) return -1; + uint32_t pe = read_instr(buffer, 0x3C); + if (pe > (uint32_t)size - 24 || memcmp(buffer + pe, "PE\0\0", 4) != 0 + || read_u16(buffer, pe + 4) != 0xAA64) return -1; + uint16_t count = read_u16(buffer, pe + 6); + uint16_t optional_size = read_u16(buffer, pe + 20); + int64_t sections = (int64_t)pe + 24 + optional_size; + if (count == 0 || optional_size < 160 || sections + (int64_t)count * 40 > size + || read_u16(buffer, pe + 24) != 0x20B + || read_instr(buffer, pe + 48) != 0 || read_instr(buffer, pe + 52) != 0) + return -1; + + int32_t slack = -1; + for (int32_t i = 0; i < count; ++i) { + int32_t section = (int32_t)sections + i * 40; + uint32_t virtual_size = read_instr(buffer, section + 8); + uint32_t rva = read_instr(buffer, section + 12); + uint32_t raw_size = read_instr(buffer, section + 16); + uint32_t raw = read_instr(buffer, section + 20); + if (raw_size == 0) continue; + if (raw != rva || (int64_t)raw + raw_size > size) return -1; + if (memcmp(buffer + section, ".text\0\0\0", 8) != 0) continue; + uint32_t mapped_size = virtual_size < raw_size ? virtual_size : raw_size; + if (slack >= 0 || mapped_size < (uint32_t)need + || !(read_instr(buffer, section + 36) & 0x40000000u)) return -1; + slack = (int32_t)(raw + mapped_size - need); + } + if (slack < 0) return -1; + for (int32_t i = 0; i < need; ++i) + if (buffer[slack + i] != 0) return -1; + if (slack_is_referenced(buffer, size, slack, need)) return -1; + + /* Reject padding which the PE loader would rewrite through relocations. */ + uint32_t directory_count = read_instr(buffer, pe + 24 + 108); + if (directory_count > 5) { + uint32_t reloc = read_instr(buffer, pe + 24 + 152); + uint32_t reloc_size = read_instr(buffer, pe + 24 + 156); + int64_t end = (int64_t)reloc + reloc_size; + if (end > size) return -1; + for (int64_t off = reloc; off < end;) { + if (end - off < 8) return -1; + uint32_t page = read_instr(buffer, (int32_t)off); + uint32_t block_size = read_instr(buffer, (int32_t)off + 4); + if (block_size < 8 || (block_size & 1) || off + block_size > end) return -1; + for (int64_t entry = off + 8; entry < off + block_size; entry += 2) { + uint16_t relocation = read_u16(buffer, (int32_t)entry); + if ((relocation >> 12) == 0) continue; + int64_t target = (int64_t)page + (relocation & 0xFFF); + if (target < (int64_t)slack + need && target + 8 > slack) return -1; + } + off += block_size; + } + } + return slack; +} + +static void redirect_reference(char* buffer, int32_t off, int32_t target) { + DecodedInst pair = decode_at(buffer, off); + int64_t delta = ((int64_t)(target & ~0xFFF) - (off & ~0xFFF)) / 4096; + uint32_t imm21 = (uint32_t)delta & 0x1FFFFF; + uint32_t adrp = 0x90000000u | ((imm21 & 3) << 29) + | ((imm21 >> 2) << 5) | pair.rt; + uint32_t add = 0x91000000u | ((uint32_t)(target & 0xFFF) << 10) + | ((uint32_t)pair.rt << 5) | pair.rt; + printf("HwCountry: redirect ADRP+ADD at 0x%X -> file:0x%X\n", off, target); + write_instr(buffer, off, adrp); + write_instr(buffer, off + 4, add); +} + +int32_t patch_hwcountry_global(char* buffer, int32_t size) { + const char value[] = "GLOBAL"; + const char line[] = "HwCountry: GLOBAL"; + if (!buffer || size < 8) return -1; + + int32_t format = find_cstring(buffer, size, "HwCountry: %a"); + if (format < 0) { + printf("HwCountry: format string not found\n"); + return -1; + } + int32_t display = find_reference(buffer, size, format); + if (display < 0) { + printf("HwCountry: format reference not found or ambiguous\n"); + return -1; + } + + /* The format call receives the country buffer in X3. */ + int32_t base_reg = -1; + uint32_t country_offset = 0; + for (int32_t i = display; i <= size - 4 && i - display <= 32; i += 4) { + DecodedInst d = decode_at(buffer, i); + if (d.type == INST_ADD_X_IMM && d.rt == 3 && d.rn != 31) { + base_reg = d.rn; + country_offset = d.imm; + break; + } + } + if (base_reg < 0) { + printf("HwCountry: country argument in X3 not found\n"); + return -1; + } + + int64_t country = -1; + for (int32_t i = display; i >= 0; i -= 4) { + DecodedInst d = decode_at(buffer, i); + if (d.type == INST_PACIASP || d.type == INST_RET) break; + if (d.type != INST_ADRP || d.rt != base_reg) continue; + int64_t base = calc_adrl_file_offset(buffer, i, 0); + if (base >= 0) { + country = base + country_offset; + break; + } + } + if (country < 0 || country >= size) { + printf("HwCountry: country buffer not found in current function\n"); + return -1; + } + int32_t getvar = find_reference(buffer, size, country); + if (getvar < 0 || getvar == display) { + printf("HwCountry: getvar reference not found or ambiguous\n"); + return -1; + } + + int32_t slack = find_slack(buffer, size, sizeof(value) + sizeof(line)); + if (slack < 0) { + printf("HwCountry: no verified ARM64 PE .text tail padding for replacement strings\n"); + return -1; + } + + /* All sites are validated before changing the buffer. */ + memcpy(buffer + slack, value, sizeof(value)); + memcpy(buffer + slack + sizeof(value), line, sizeof(line)); + redirect_reference(buffer, getvar, slack); + redirect_reference(buffer, display, slack + sizeof(value)); + printf("HwCountry -> GLOBAL applied\n"); + return 0; +} diff --git a/submodules/patcher/tests/test_hwcountry.c b/submodules/patcher/tests/test_hwcountry.c new file mode 100644 index 000000000..a467814a5 --- /dev/null +++ b/submodules/patcher/tests/test_hwcountry.c @@ -0,0 +1,106 @@ +#include "arm64_inst/utils.h" +#include "patchs/xiaomi/hwcountry.h" +#ifdef NDEBUG +#undef NDEBUG +#endif +#include +#include + +enum { SIZE = 0x2000, SECTION = 0x188, DISPLAY = 0x310, GETVAR = 0x1300, + FORMAT = 0x900, COUNTRY = 0xB00, SLACK = 0x1000 - 25 }; + +static void put16(char* data, int32_t off, uint16_t value) { + memcpy(data + off, &value, sizeof(value)); +} + +/* Only the PE header and the instructions used by the patch are populated. */ +static void fixture(char* data) { + memset(data, 0, SIZE); + memcpy(data, "MZ", 2); + write_instr(data, 0x3C, 0x80); + memcpy(data + 0x80, "PE\0\0", 4); + put16(data, 0x84, 0xAA64); + put16(data, 0x86, 2); + put16(data, 0x94, 0xF0); + put16(data, 0x98, 0x20B); + memcpy(data + SECTION, ".text", 5); + write_instr(data, SECTION + 8, 0xE00); + write_instr(data, SECTION + 12, 0x200); + write_instr(data, SECTION + 16, 0xE00); + write_instr(data, SECTION + 20, 0x200); + write_instr(data, SECTION + 36, 0x60000020); + memcpy(data + SECTION + 40, ".data", 5); + write_instr(data, SECTION + 48, 0x1000); + write_instr(data, SECTION + 52, 0x1000); + write_instr(data, SECTION + 56, 0x1000); + write_instr(data, SECTION + 60, 0x1000); + write_instr(data, SECTION + 76, 0xC0000040); + memcpy(data + FORMAT, "HwCountry: %a", 14); + write_instr(data, 0x300, 0xD503233F); /* PACIASP */ + write_instr(data, 0x304, 0x90000014); /* ADRP X20, page 0 */ + write_instr(data, 0x308, 0x91280294); /* ADD X20, X20, #0xA00 */ + write_instr(data, DISPLAY, 0x90000002); + write_instr(data, DISPLAY + 4, 0x91240042); /* X2 -> format */ + write_instr(data, DISPLAY + 8, 0x91040283); /* ADD X3, X20, #0x100 */ + write_instr(data, GETVAR, 0xF0FFFFE0); /* ADRP X0, previous page */ + write_instr(data, GETVAR + 4, 0x912C0000); /* ADD X0, X0, #0xB00 */ + assert(calc_adrl_file_offset(data, GETVAR, 0) == COUNTRY); +} + +static void expect_failure_unchanged(char* data) { + char before[SIZE]; + memcpy(before, data, SIZE); + assert(patch_hwcountry_global(data, SIZE) == -1); + assert(memcmp(before, data, SIZE) == 0); +} + +int main(void) { + char data[SIZE]; + fixture(data); + char before[SIZE]; + memcpy(before, data, SIZE); + assert(patch_hwcountry_global(data, SIZE) == 0); + assert(calc_adrl_file_offset(data, GETVAR, 0) == SLACK); + assert(calc_adrl_file_offset(data, DISPLAY, 0) == SLACK + 7); + assert(strcmp(data + SLACK, "GLOBAL") == 0); + assert(strcmp(data + SLACK + 7, "HwCountry: GLOBAL") == 0); + for (int32_t i = 0; i < SIZE; ++i) { + if ((i >= GETVAR && i < GETVAR + 8) || (i >= DISPLAY && i < DISPLAY + 8) + || (i >= SLACK && i < SLACK + 25)) continue; + assert(data[i] == before[i]); + } + + fixture(data); + data[FORMAT] = 'X'; + expect_failure_unchanged(data); + + fixture(data); + data[0xFFF] = 1; /* Occupied tail must not be overwritten. */ + expect_failure_unchanged(data); + + fixture(data); + memcpy(data + GETVAR + 16, data + GETVAR, 8); /* Ambiguous getvar. */ + expect_failure_unchanged(data); + + fixture(data); + write_instr(data, SECTION + 12, 0x400); /* Non-flat PE mapping. */ + expect_failure_unchanged(data); + + fixture(data); + write_instr(data, 0x500, 0x90000005); + write_instr(data, 0x504, 0x913F9CA5); /* Existing reference to tail padding. */ + assert(calc_adrl_file_offset(data, 0x500, 0) == SLACK); + expect_failure_unchanged(data); + + fixture(data); + write_instr(data, 0x104, 6); /* NumberOfRvaAndSizes. */ + write_instr(data, 0x130, 0x1800); /* Base relocation directory. */ + write_instr(data, 0x134, 10); + write_instr(data, 0x1800, 0); + write_instr(data, 0x1804, 10); + put16(data, 0x1808, 0xA000 | SLACK); /* DIR64 relocation into padding. */ + expect_failure_unchanged(data); + + puts("HwCountry tests passed (success and six rejected layouts)"); + return EXIT_SUCCESS; +} diff --git a/targets/toolkit_android/resources/build.sh b/targets/toolkit_android/resources/build.sh index 528d5c898..cb99ac875 100644 --- a/targets/toolkit_android/resources/build.sh +++ b/targets/toolkit_android/resources/build.sh @@ -11,7 +11,7 @@ if [ ! -f ./LinuxLoader.efi ]; then fi mv ./LinuxLoader.efi ./ABL_original.efi -if ! ./bin/patch_abl ./ABL_original.efi ./efisp/boot.efi > ./patch_log.txt 2>&1; then +if ! ./bin/patch_abl ./ABL_original.efi ./efisp/boot.efi "$@" > ./patch_log.txt 2>&1; then cat ./patch_log.txt echo "ERROR: patch_abl failed" exit 1 diff --git a/targets/toolkit_linux/resources/build.sh b/targets/toolkit_linux/resources/build.sh index 52b9e0c30..11420613d 100644 --- a/targets/toolkit_linux/resources/build.sh +++ b/targets/toolkit_linux/resources/build.sh @@ -10,7 +10,7 @@ if [ ! -f ./LinuxLoader.efi ]; then fi mv ./LinuxLoader.efi ./ABL_original.efi -if ! ./bin/patch_abl ./ABL_original.efi ./efisp/boot.efi > ./patch_log.txt 2>&1; then +if ! ./bin/patch_abl ./ABL_original.efi ./efisp/boot.efi "$@" > ./patch_log.txt 2>&1; then cat ./patch_log.txt echo "ERROR: patch_abl failed" exit 1 diff --git a/targets/toolkit_windows/resources/build.bat b/targets/toolkit_windows/resources/build.bat index 476a44139..c3cb777b0 100644 --- a/targets/toolkit_windows/resources/build.bat +++ b/targets/toolkit_windows/resources/build.bat @@ -9,7 +9,7 @@ if not exist extracted\LinuxLoader.efi ( exit /b 1 ) move /Y extracted\LinuxLoader.efi ABL_original.efi >nul -bin\patch_abl ABL_original.efi efisp\boot.efi > patch_log.txt 2>&1 +bin\patch_abl ABL_original.efi efisp\boot.efi %* > patch_log.txt 2>&1 if errorlevel 1 ( type patch_log.txt echo ERROR: patch_abl failed @@ -25,7 +25,7 @@ set GBL_OK=yes findstr /C:"Warning: Failed to patch ABL GBL" patch_log.txt >nul && ( set GBL_OK=no echo. - echo WARNING: No GBL exploit found in this ABL (Failed to patch ABL GBL). + echo WARNING: No GBL exploit found in this ABL: Failed to patch ABL GBL. echo efisp/boot.efi is still produced and valid, but the abl partition must be echo downgraded to an older ABL with the GBL vulnerability before booting. echo 警告:此 ABL 中未找到 GBL 漏洞(Failed to patch ABL GBL)。 @@ -51,7 +51,7 @@ echo (create /mnt/vendor/persist/efisp first if needed, e.g. via MT Manager) echo 2. sync if "%GBL_OK%"=="no" ( echo 3. Downgrade the abl partition to an older ABL with the GBL vulnerability - echo (efisp/boot.efi and the abl partition do not need to match versions) + echo efisp/boot.efi and the abl partition do not need to match versions echo 4. Flash BDS.efi to the efisp partition: echo dd if=BDS.efi of=/dev/block/by-name/efisp bs=4M ) else (