From 56dc5dc37349b984e2b1f38b3bdb025c262429bd Mon Sep 17 00:00:00 2001 From: root Date: Wed, 21 Jan 2026 00:44:52 -0600 Subject: [PATCH 01/10] add auto-hwid --- database/cros-hwid.json | 233 ++++++++++++++++++++++++++++++++++++++++ firmware.sh | 161 ++++++++++++++++++++++++++- generate-hwid.sh | 151 ++++++++++++++++++++++++++ 3 files changed, 541 insertions(+), 4 deletions(-) create mode 100644 database/cros-hwid.json create mode 100755 generate-hwid.sh diff --git a/database/cros-hwid.json b/database/cros-hwid.json new file mode 100644 index 0000000..a4743b3 --- /dev/null +++ b/database/cros-hwid.json @@ -0,0 +1,233 @@ +{ + "_meta": { + "schema": "codename_to_hwid_min.v1", + "updated": "2026-01-20", + "fields": { + "hwid": "string", + "owner_history": "enum: clean|unknown|suspected_bad|proven_bad", + "confidence_valid": "0.0-1.0", + "confidence_allegation": "0.0-1.0", + "notes": "short string (optional)" + } + }, + "devices": { + "HANA": [ + { + "hwid": "HANA L4A-D75-C2H-E2Q-P2U-B4Q", + "owner_history": "proven_bad", + "confidence_valid": 1, + "confidence_allegation": 1, + "notes": "Proven enrolled/linked to an organization" + }, + { + "hwid": "HANA 14A-D7K-A2A-G2Q-B2W-A83", + "owner_history": "suspected_bad", + "confidence_valid": 1, + "confidence_allegation": 0.1, + "notes": "Suspected org enrollment" + }, + { + "hwid": "HANA 14A-D7Z-A6E-A2I-D2E-B9K", + "owner_history": "suspected_bad", + "confidence_valid": 1, + "confidence_allegation": 0.1, + "notes": "Suspected org enrollment" + } + ], + "SHYVANA": [ + { + "hwid": "SHYVANA C5B-A4G-C4Q-S24-A9U", + "owner_history": "unknown", + "confidence_valid": 1, + "confidence_allegation": 0.5 + } + ], + "JINLON-YTGY": [ + { + "hwid": "JINLON-YTGY C5B-O5B-E4E-S3Q-E9L", + "owner_history": "unknown", + "confidence_valid": 1, + "confidence_allegation": 0.5, + "notes": "Unsure" + } + ], + "KIP": [ + { + "hwid": "KIP C5A-G2O-H6A-A5V", + "owner_history": "unknown", + "confidence_valid": 1, + "confidence_allegation": 0.5 + } + ], + "EVE": [ + { + "hwid": "EVE D6B-A6A-C4C-F8N-P8A-A37", + "owner_history": "unknown", + "confidence_valid": 1, + "confidence_allegation": 0.5 + } + ], + "GRABBITER": [ + { + "hwid": "GRABBITER G7B-B4E-O57-L8M-E6T-Q8Q-A2K", + "owner_history": "unknown", + "confidence_valid": 0.5, + "confidence_allegation": 0.3, + "notes": "Suspected org enrollment; reason: owner's tpm BAD" + }, + { + "hwid": "GRABBITER D6B-B3C-C5P-M8I-C6Y-A72", + "owner_history": "suspected_bad", + "confidence_valid": 1, + "confidence_allegation": 0.3, + "notes": "Suspected org enrollment; reason: owner's tpm BAD" + }, + { + "hwid": "GRABBITER G7C-B4C-O52-M4Y-C8T-Q8Q-A2M", + "owner_history": "suspected_bad", + "confidence_valid": 1, + "confidence_allegation": 0.3, + "notes": "Suspected org enrollment" + } + ], + "NASHER": [ + { + "hwid": "NASHER D5F-B4K-C47-W5K-S4C-I6A-A9A", + "owner_history": "unknown", + "confidence_valid": 1, + "confidence_allegation": 0.5, + "notes": "Unsure" + } + ], + "BARLA": [ + { + "hwid": "BARLA C4B-A4L-F3V-M8G-I2Q-C2E-A8B", + "owner_history": "unknown", + "confidence_valid": 1, + "confidence_allegation": 0.5 + } + ], + "FLEEX": [ + { + "hwid": "FLEEX D7B-B4D-G57-N8N-J4M-G2Q-A6D", + "owner_history": "proven_bad", + "confidence_valid": 1, + "confidence_allegation": 1, + "notes": "Proven enrolled/linked to an organization" + }, + { + "hwid": "FLEEX D7B-B4B-H5V-N2B-A4M-H2M", + "owner_history": "suspected_bad", + "confidence_valid": 1, + "confidence_allegation": 0.3, + "notes": "Suspected org enrollment; reason: owner's tpm BAD" + }, + { + "hwid": "FLEEX D6B-B3D-G5V-P3J-B4E-B7K", + "owner_history": "suspected_bad", + "confidence_valid": 1, + "confidence_allegation": 0.3, + "notes": "Suspected org enrollment; reason: owner's tpm BAD" + } + ], + "FALCO": [ + { + "hwid": "FALCO C3J-C3I-P8N", + "owner_history": "unknown", + "confidence_valid": 1, + "confidence_allegation": 0.5 + }, + { + "hwid": "FALCO C2A-U6Y-D95", + "owner_history": "unknown", + "confidence_valid": 1, + "confidence_allegation": 0.5 + } + ], + "BLOOGET": [ + { + "hwid": "BLOOGET C2Q-A4D-D2K-T7X-U8A-A9N", + "owner_history": "suspected_bad", + "confidence_valid": 1, + "confidence_allegation": 0.3, + "notes": "Suspected org enrollment; reason: owner's tpm BAD" + } + ], + "GNAWTY": [ + { + "hwid": "GNAWTY C2Q-E55-A5B", + "owner_history": "unknown", + "confidence_valid": 1, + "confidence_allegation": 0.5 + } + ], + "MINNIE": [ + { + "hwid": "MINNIE F25-S2E-Q4G-A3C", + "owner_history": "unknown", + "confidence_valid": 1, + "confidence_allegation": 0.5 + } + ], + "NAUTILUS": [ + { + "hwid": "NAUTILUS D5B-A2E-B5M-D97-Q34", + "owner_history": "suspected_bad", + "confidence_valid": 1, + "confidence_allegation": 0.3, + "notes": "Suspected org enrollment; reason: owner's tpm BAD" + } + ], + "AKALI360": [ + { + "hwid": "AKALI360 C4B-A2C-F3K-65U-I8T", + "owner_history": "suspected_bad", + "confidence_valid": 1, + "confidence_allegation": 0.3, + "notes": "Suspected org enrollment; reason: owner's tpm BAD" + } + ], + "PEPPY": [ + { + "hwid": "PEPPY C3A-B3E-A3D", + "owner_history": "unknown", + "confidence_valid": 1, + "confidence_allegation": 0.5 + } + ], + "BANJO": [ + { + "hwid": "BANJO C7A-C2I-A65", + "owner_history": "unknown", + "confidence_valid": 1, + "confidence_allegation": 0.5 + } + ], + "LASER14": [ + { + "hwid": "LASER14 C3J-A2E-A3K-I4Q-I4I", + "owner_history": "suspected_bad", + "confidence_valid": 1, + "confidence_allegation": 0.3, + "notes": "Suspected org enrollment; reason: owner's tpm BAD" + } + ], + "GANDOF": [ + { + "hwid": "GANDOF D25-A4W-B3Q-A6E", + "owner_history": "unknown", + "confidence_valid": 1, + "confidence_allegation": 0.5 + } + ], + "CAREENA": [ + { + "hwid": "CAREENA C5B-A41-D4Q-A3Y-O6R-A2B-E9E", + "owner_history": "suspected_bad", + "confidence_valid": 0.8, + "confidence_allegation": 0.3, + "notes": "Suspected org enrollment; reason: owner's tpm BAD" + } + ] + } +} diff --git a/firmware.sh b/firmware.sh index 658cddd..0b298c1 100644 --- a/firmware.sh +++ b/firmware.sh @@ -1422,6 +1422,150 @@ You can always override the default using [CTRL+D] or ################### # Set Hardware ID # ################### +function fixcraft_hwid_db_path() { + local script_dir + script_dir=$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) + echo "${script_dir}/database/cros-hwid.json" +} + +function fixcraft_hwid_download_db() { + local url="https://www.fixcraft.jp/database/cros-hwid.json" + local out="/tmp/fixcraft-cros-hwid.json" + + if [[ -n "${CURL:-}" ]]; then + if ${CURL} -fsSL "${url}" -o "${out}" >/dev/null 2>&1; then + echo "${out}" + return 0 + fi + fi + + if command -v curl >/dev/null 2>&1; then + if curl -fsSL "${url}" -o "${out}" >/dev/null 2>&1; then + echo "${out}" + return 0 + fi + fi + + if command -v wget >/dev/null 2>&1; then + if wget -qO "${out}" "${url}" >/dev/null 2>&1; then + echo "${out}" + return 0 + fi + fi + + return 1 +} + +function fixcraft_hwid_lookup_predefined() { + local db_file="$1" + local board="$2" + + awk -v board="$board" ' + $0 ~ "\"" board "\"[[:space:]]*:[[:space:]]*\\[" { in=1; next } + in && /"hwid"[[:space:]]*:/ { + match($0, /"hwid"[[:space:]]*:[[:space:]]*"[^"]+"/) + if (RSTART) { + hwid=substr($0, RSTART, RLENGTH) + sub(/.*"hwid"[[:space:]]*:[[:space:]]*"/, "", hwid) + sub(/"$/, "", hwid) + print hwid + exit + } + } + in && /]/ { exit } + ' "${db_file}" +} + +function fixcraft_hwid_generate() { + local board="$1" + local script_dir + script_dir=$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) + local gen_script="${script_dir}/generate-hwid.sh" + + if [[ ! -x "${gen_script}" ]]; then + return 1 + fi + + "${gen_script}" --board "${board}" +} + +function select_new_hwid() { + local current_hwid="$1" + local board="" + local hwid="" + local confirm="" + + if [[ -n "${current_hwid}" ]]; then + board=$(echo "${current_hwid^^}" | cut -f1 -d ' ') + elif [[ -n "${boardName:-}" ]]; then + board="${boardName^^}" + elif [[ -n "${device:-}" ]]; then + board="${device^^}" + fi + + if [[ -z "${board}" ]]; then + read -rep "Enter your board name: " board + board=$(printf '%s' "${board}" | tr '[:lower:]' '[:upper:]') + fi + if [[ -z "${board}" ]]; then + echo_red "No board name provided; operation cancelled." + return 1 + fi + + read -rep "Do you want to try using a working, pre-defined ID? [y/N] " confirm + if [[ "${confirm}" = "Y" || "${confirm}" = "y" ]]; then + local db_file="" + db_file=$(fixcraft_hwid_download_db) || true + if [[ -z "${db_file}" ]]; then + db_file=$(fixcraft_hwid_db_path) + fi + + if [[ -s "${db_file}" ]]; then + hwid=$(fixcraft_hwid_lookup_predefined "${db_file}" "${board}") + fi + + if [[ -z "${hwid}" ]]; then + echo_yellow "looks like your device isnt in the FixCraft Database!" + hwid=$(fixcraft_hwid_generate "${board}") || true + if [[ -n "${hwid}" ]]; then + echo "${hwid}" + return 0 + fi + else + read -rep "Use pre-defined ID ${hwid}? [y/N] " confirm + if [[ "${confirm}" = "Y" || "${confirm}" = "y" ]]; then + echo "${hwid}" + return 0 + fi + fi + fi + + while true; do + read -rep "Auto-generate for your board or enter manually? [A/M] " confirm + if [[ "${confirm}" = "A" || "${confirm}" = "a" ]]; then + hwid=$(fixcraft_hwid_generate "${board}") || true + if [[ -n "${hwid}" ]]; then + echo "${hwid}" + return 0 + fi + echo_yellow "Unable to auto-generate HWID; please enter manually." + elif [[ "${confirm}" = "M" || "${confirm}" = "m" ]]; then + read -rep "Type 'I KNOW WHAT IM DOING' to continue: " confirm + if [[ "${confirm}" != "I KNOW WHAT IM DOING" ]]; then + echo_red "Confirmation phrase not entered; operation cancelled." + return 1 + fi + read -rep "Enter a new HWID (use all caps): " hwid + if [[ -z "${hwid}" ]]; then + echo_red "No HWID entered; operation cancelled." + return 1 + fi + echo "${hwid}" + return 0 + fi + done +} + function set_hwid() { # set HWID using gbb_utility @@ -1448,7 +1592,14 @@ Proceed at your own risk." read -rep "This is serious. Are you really sure? [y/N] " confirm [[ "$confirm" = "Y" || "$confirm" = "y" ]] || return - read -rep "Enter a new HWID (use all caps): " hwid + local hwid="" + if ! hwid=$(select_new_hwid "${_hwid}"); then + return + fi + if [[ -z "${hwid}" ]]; then + exit_red "No HWID selected; operation cancelled."; return 1 + fi + echo -e "" read -rep "Confirm changing HWID to $hwid [y/N] " confirm if [[ "$confirm" = "Y" || "$confirm" = "y" ]]; then @@ -1508,9 +1659,11 @@ Proceed at your own risk." [[ "$confirm" = "Y" || "$confirm" = "y" ]] || return local hwid="" - read -rep "Enter a new HWID: " hwid - if [[ -z "$hwid" ]]; then - exit_red "No HWID entered; operation cancelled."; return 1 + if ! hwid=$(select_new_hwid "${_current_hwid}"); then + return + fi + if [[ -z "${hwid}" ]]; then + exit_red "No HWID selected; operation cancelled."; return 1 fi echo -e "" diff --git a/generate-hwid.sh b/generate-hwid.sh new file mode 100755 index 0000000..c2c78eb --- /dev/null +++ b/generate-hwid.sh @@ -0,0 +1,151 @@ +#!/usr/bin/env bash +set -euo pipefail + +usage() { + echo "Usage: $0 --board BOARD" >&2 +} + +board="" +while [ "$#" -gt 0 ]; do + case "$1" in + --board) + board=${2:-} + shift 2 + ;; + --help|-h) + usage + exit 0 + ;; + *) + usage + exit 1 + ;; + esac +done + +if [ -z "$board" ]; then + usage + exit 1 +fi + +board=$(printf '%s' "$board" | tr '[:lower:]' '[:upper:]') +script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +data_file="$script_dir/database/cros-hwid.json" + +node_bin="" +if command -v node >/dev/null 2>&1; then + node_bin="node" +elif command -v nodejs >/dev/null 2>&1; then + node_bin="nodejs" +else + echo "Error: node (or nodejs) is required to run this script." >&2 + exit 1 +fi + +"$node_bin" - <<'NODE' "$data_file" "$board" +const fs = require("fs"); +const file = process.argv[2]; +const board = process.argv[3]; +if (!file || !board) { + console.error("Usage: generate-hwid.sh --board BOARD"); + process.exit(1); +} +const data = JSON.parse(fs.readFileSync(file, "utf8")); +const devices = data.devices || {}; + +function randInt(n) { + return Math.floor(Math.random() * n); +} + +function pick(arr) { + return arr[randInt(arr.length)]; +} + +function parseGroups(hwid) { + if (!hwid) return []; + const parts = String(hwid).split(" "); + if (parts.length < 2) return []; + return parts.slice(1).join(" ").split("-").filter(Boolean); +} + +function flattenEntries(map) { + const all = []; + for (const entries of Object.values(map)) { + if (!Array.isArray(entries)) continue; + for (const entry of entries) { + if (entry && entry.hwid) all.push(entry); + } + } + return all; +} + +function charPattern(group) { + let hexOnly = true; + const pattern = []; + for (const ch of group) { + if (ch >= "0" && ch <= "9") { + pattern.push("D"); + } else if (ch >= "A" && ch <= "Z") { + pattern.push("A"); + } else { + pattern.push("X"); + } + if (!((ch >= "0" && ch <= "9") || (ch >= "A" && ch <= "F"))) { + hexOnly = false; + } + } + return { pattern: pattern.join(""), hexOnly }; +} + +function genChar(type, hexOnly) { + if (type === "D") { + return String(randInt(10)); + } + if (type === "A") { + const letters = hexOnly ? "ABCDEF" : "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + return letters[randInt(letters.length)]; + } + const pool = hexOnly + ? "0123456789ABCDEF" + : "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + return pool[randInt(pool.length)]; +} + +function genGroupFromTemplate(group) { + const { pattern, hexOnly } = charPattern(group); + if (!pattern) return ""; + let out = ""; + for (const t of pattern) { + out += genChar(t, hexOnly); + } + return out; +} + +const entries = devices[board]; +let pool = entries; +if (!Array.isArray(pool) || pool.length === 0) { + console.error("Board unsupported, trying random"); + pool = flattenEntries(devices); +} + +let groups = []; +if (pool.length > 0) { + const template = pick(pool); + groups = parseGroups(template.hwid); +} + +const groupCount = groups.length || 4; +const prefixLen = Math.min(2, groupCount); +const outGroups = []; + +for (let i = 0; i < groupCount; i++) { + if (i < prefixLen && groups[i]) { + outGroups.push(groups[i]); + continue; + } + const templateGroup = groups[i] || "A0Z"; + outGroups.push(genGroupFromTemplate(templateGroup)); +} + +console.log(`${board} ${outGroups.join("-")}`); +NODE From 2cdab59271e5805303e66d7bc6bb8ce62a32d2b7 Mon Sep 17 00:00:00 2001 From: F1xGOD FWS Date: Wed, 21 Jan 2026 01:14:39 -0600 Subject: [PATCH 02/10] GG --- firmware.sh | 6 +- generate-hwid.sh | 207 +++++++++++++++++++++-------------------------- 2 files changed, 97 insertions(+), 116 deletions(-) diff --git a/firmware.sh b/firmware.sh index 0b298c1..cb9c898 100644 --- a/firmware.sh +++ b/firmware.sh @@ -1461,8 +1461,8 @@ function fixcraft_hwid_lookup_predefined() { local board="$2" awk -v board="$board" ' - $0 ~ "\"" board "\"[[:space:]]*:[[:space:]]*\\[" { in=1; next } - in && /"hwid"[[:space:]]*:/ { + $0 ~ "\"" board "\"[[:space:]]*:[[:space:]]*\\[" { in_block=1; next } + in_block && /"hwid"[[:space:]]*:/ { match($0, /"hwid"[[:space:]]*:[[:space:]]*"[^"]+"/) if (RSTART) { hwid=substr($0, RSTART, RLENGTH) @@ -1472,7 +1472,7 @@ function fixcraft_hwid_lookup_predefined() { exit } } - in && /]/ { exit } + in_block && /]/ { exit } ' "${db_file}" } diff --git a/generate-hwid.sh b/generate-hwid.sh index c2c78eb..ea05c2f 100755 --- a/generate-hwid.sh +++ b/generate-hwid.sh @@ -32,120 +32,101 @@ board=$(printf '%s' "$board" | tr '[:lower:]' '[:upper:]') script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) data_file="$script_dir/database/cros-hwid.json" -node_bin="" -if command -v node >/dev/null 2>&1; then - node_bin="node" -elif command -v nodejs >/dev/null 2>&1; then - node_bin="nodejs" +py_bin="" +if command -v python3 >/dev/null 2>&1; then + py_bin="python3" +elif command -v python >/dev/null 2>&1; then + py_bin="python" else - echo "Error: node (or nodejs) is required to run this script." >&2 + echo "Error: python3 (or python) is required to run this script." >&2 exit 1 fi -"$node_bin" - <<'NODE' "$data_file" "$board" -const fs = require("fs"); -const file = process.argv[2]; -const board = process.argv[3]; -if (!file || !board) { - console.error("Usage: generate-hwid.sh --board BOARD"); - process.exit(1); -} -const data = JSON.parse(fs.readFileSync(file, "utf8")); -const devices = data.devices || {}; - -function randInt(n) { - return Math.floor(Math.random() * n); -} - -function pick(arr) { - return arr[randInt(arr.length)]; -} - -function parseGroups(hwid) { - if (!hwid) return []; - const parts = String(hwid).split(" "); - if (parts.length < 2) return []; - return parts.slice(1).join(" ").split("-").filter(Boolean); -} - -function flattenEntries(map) { - const all = []; - for (const entries of Object.values(map)) { - if (!Array.isArray(entries)) continue; - for (const entry of entries) { - if (entry && entry.hwid) all.push(entry); - } - } - return all; -} - -function charPattern(group) { - let hexOnly = true; - const pattern = []; - for (const ch of group) { - if (ch >= "0" && ch <= "9") { - pattern.push("D"); - } else if (ch >= "A" && ch <= "Z") { - pattern.push("A"); - } else { - pattern.push("X"); - } - if (!((ch >= "0" && ch <= "9") || (ch >= "A" && ch <= "F"))) { - hexOnly = false; - } - } - return { pattern: pattern.join(""), hexOnly }; -} - -function genChar(type, hexOnly) { - if (type === "D") { - return String(randInt(10)); - } - if (type === "A") { - const letters = hexOnly ? "ABCDEF" : "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - return letters[randInt(letters.length)]; - } - const pool = hexOnly - ? "0123456789ABCDEF" - : "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - return pool[randInt(pool.length)]; -} - -function genGroupFromTemplate(group) { - const { pattern, hexOnly } = charPattern(group); - if (!pattern) return ""; - let out = ""; - for (const t of pattern) { - out += genChar(t, hexOnly); - } - return out; -} - -const entries = devices[board]; -let pool = entries; -if (!Array.isArray(pool) || pool.length === 0) { - console.error("Board unsupported, trying random"); - pool = flattenEntries(devices); -} - -let groups = []; -if (pool.length > 0) { - const template = pick(pool); - groups = parseGroups(template.hwid); -} - -const groupCount = groups.length || 4; -const prefixLen = Math.min(2, groupCount); -const outGroups = []; - -for (let i = 0; i < groupCount; i++) { - if (i < prefixLen && groups[i]) { - outGroups.push(groups[i]); - continue; - } - const templateGroup = groups[i] || "A0Z"; - outGroups.push(genGroupFromTemplate(templateGroup)); -} - -console.log(`${board} ${outGroups.join("-")}`); -NODE +"$py_bin" - "$data_file" "$board" <<'PY' +import json +import random +import sys + +if len(sys.argv) < 3: + print("Usage: generate-hwid.sh --board BOARD", file=sys.stderr) + sys.exit(1) + +db_file = sys.argv[1] +board = sys.argv[2] + +with open(db_file, "r", encoding="utf-8") as fh: + data = json.load(fh) + +devices = data.get("devices", {}) + +def parse_groups(hwid): + if not hwid: + return [] + parts = str(hwid).split(" ") + if len(parts) < 2: + return [] + return [g for g in "-".join(parts[1:]).split("-") if g] + +def flatten_entries(device_map): + all_entries = [] + for entries in device_map.values(): + if not isinstance(entries, list): + continue + for entry in entries: + if isinstance(entry, dict) and entry.get("hwid"): + all_entries.append(entry) + return all_entries + +def char_pattern(group): + hex_only = True + pattern = [] + for ch in group: + if "0" <= ch <= "9": + pattern.append("D") + elif "A" <= ch <= "Z": + pattern.append("A") + else: + pattern.append("X") + if not (("0" <= ch <= "9") or ("A" <= ch <= "F")): + hex_only = False + return "".join(pattern), hex_only + +def gen_char(char_type, hex_only): + if char_type == "D": + return str(random.randrange(10)) + if char_type == "A": + letters = "ABCDEF" if hex_only else "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + return random.choice(letters) + pool = "0123456789ABCDEF" if hex_only else "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + return random.choice(pool) + +def gen_group_from_template(group): + pattern, hex_only = char_pattern(group) + if not pattern: + return "" + return "".join(gen_char(t, hex_only) for t in pattern) + +entries = devices.get(board) +pool = entries if isinstance(entries, list) else None +if not pool: + print("Board unsupported, trying random", file=sys.stderr) + pool = flatten_entries(devices) + +groups = [] +if pool: + template = random.choice(pool) + groups = parse_groups(template.get("hwid")) + +group_count = len(groups) or 4 +prefix_len = min(2, group_count) +out_groups = [] + +for i in range(group_count): + if i < prefix_len and i < len(groups) and groups[i]: + out_groups.append(groups[i]) + continue + template_group = groups[i] if i < len(groups) and groups[i] else "A0Z" + out_groups.append(gen_group_from_template(template_group)) + +print(f"{board} {'-'.join(out_groups)}") +PY From 0e4514a369f60c971c6b829d0ec9b56c4ce4d1ec Mon Sep 17 00:00:00 2001 From: F1xGOD FWS Date: Wed, 21 Jan 2026 01:49:29 -0600 Subject: [PATCH 03/10] GG --- firmware.sh | 157 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 137 insertions(+), 20 deletions(-) diff --git a/firmware.sh b/firmware.sh index cb9c898..532e972 100644 --- a/firmware.sh +++ b/firmware.sh @@ -1428,6 +1428,18 @@ function fixcraft_hwid_db_path() { echo "${script_dir}/database/cros-hwid.json" } +function fixcraft_find_python() { + if command -v python3 >/dev/null 2>&1; then + echo "python3" + return 0 + fi + if command -v python >/dev/null 2>&1; then + echo "python" + return 0 + fi + return 1 +} + function fixcraft_hwid_download_db() { local url="https://www.fixcraft.jp/database/cros-hwid.json" local out="/tmp/fixcraft-cros-hwid.json" @@ -1456,6 +1468,97 @@ function fixcraft_hwid_download_db() { return 1 } +function fixcraft_hwid_select_predefined() { + local db_file="$1" + local board="$2" + local py_bin="" + local lines="" + local status=0 + + py_bin=$(fixcraft_find_python) || { echo_yellow "Python not found; skipping pre-defined IDs." >&2; return 3; } + + lines=$("$py_bin" - "$db_file" "$board" <<'PY') +import json +import sys + +if len(sys.argv) < 3: + sys.exit(3) + +db_file = sys.argv[1] +board = sys.argv[2] + +try: + with open(db_file, "r", encoding="utf-8") as fh: + data = json.load(fh) +except Exception: + sys.exit(3) + +entries = data.get("devices", {}).get(board, []) +items = [] + +def to_float(val, default): + try: + return float(val) + except Exception: + return default + +for entry in entries: + if not isinstance(entry, dict): + continue + hwid = entry.get("hwid") + if not hwid: + continue + valid = to_float(entry.get("confidence_valid", 1.0), 1.0) + allegation = to_float(entry.get("confidence_allegation", 1.0), 1.0) + items.append((hwid, valid, allegation)) + +if not items: + sys.exit(1) + +best_idx = min(range(len(items)), key=lambda i: (items[i][2], -items[i][1], i)) +for i, (hwid, valid, allegation) in enumerate(items, 1): + rec = 1 if (i - 1) == best_idx else 0 + print(f"{i}|{hwid}|{valid}|{allegation}|{rec}") +PY + status=$? + if [[ $status -eq 1 ]]; then + return 1 + fi + if [[ $status -ne 0 || -z "${lines}" ]]; then + echo_yellow "Unable to read FixCraft database; skipping pre-defined IDs." >&2 + return 3 + fi + + echo "Pick an HWID:" >&2 + while IFS='|' read -r idx hwid valid allegation rec; do + [[ -z "${idx}" || -z "${hwid}" ]] && continue + local label="" + if [[ "${rec}" = "1" ]]; then + label=" [RECOMMENDED]" + fi + printf "%s. %s (valid %s, allegation %s)%s\n" "${idx}" "${hwid}" "${valid}" "${allegation}" "${label}" >&2 + done <<< "${lines}" + + local choice="" + local selected="" + while true; do + read -rep "Select a number (or press Enter to cancel): " choice + if [[ -z "${choice}" ]]; then + return 2 + fi + if ! [[ "${choice}" =~ ^[0-9]+$ ]]; then + echo_yellow "Invalid selection." >&2 + continue + fi + selected=$(awk -F'|' -v pick="${choice}" '$1==pick {print $2; exit}' <<< "${lines}") + if [[ -n "${selected}" ]]; then + echo "${selected}" + return 0 + fi + echo_yellow "Invalid selection." >&2 + done +} + function fixcraft_hwid_lookup_predefined() { local db_file="$1" local board="$2" @@ -1489,6 +1592,23 @@ function fixcraft_hwid_generate() { "${gen_script}" --board "${board}" } +function fixcraft_hwid_manual() { + local confirm="" + local hwid="" + + read -rep "Type 'I KNOW WHAT IM DOING' to continue: " confirm + if [[ "${confirm}" != "I KNOW WHAT IM DOING" ]]; then + echo_red "Confirmation phrase not entered; operation cancelled." >&2 + return 1 + fi + read -rep "Enter a new HWID (use all caps): " hwid + if [[ -z "${hwid}" ]]; then + echo_red "No HWID entered; operation cancelled." >&2 + return 1 + fi + echo "${hwid}" +} + function select_new_hwid() { local current_hwid="$1" local board="" @@ -1515,25 +1635,24 @@ function select_new_hwid() { read -rep "Do you want to try using a working, pre-defined ID? [y/N] " confirm if [[ "${confirm}" = "Y" || "${confirm}" = "y" ]]; then local db_file="" + local status=0 db_file=$(fixcraft_hwid_download_db) || true if [[ -z "${db_file}" ]]; then db_file=$(fixcraft_hwid_db_path) fi if [[ -s "${db_file}" ]]; then - hwid=$(fixcraft_hwid_lookup_predefined "${db_file}" "${board}") - fi - - if [[ -z "${hwid}" ]]; then - echo_yellow "looks like your device isnt in the FixCraft Database!" - hwid=$(fixcraft_hwid_generate "${board}") || true + hwid=$(fixcraft_hwid_select_predefined "${db_file}" "${board}") || status=$? if [[ -n "${hwid}" ]]; then echo "${hwid}" return 0 fi - else - read -rep "Use pre-defined ID ${hwid}? [y/N] " confirm - if [[ "${confirm}" = "Y" || "${confirm}" = "y" ]]; then + fi + + if [[ ${status} -eq 1 ]]; then + echo_yellow "looks like your device isnt in the FixCraft Database!" >&2 + hwid=$(fixcraft_hwid_generate "${board}") || true + if [[ -n "${hwid}" ]]; then echo "${hwid}" return 0 fi @@ -1548,18 +1667,16 @@ function select_new_hwid() { echo "${hwid}" return 0 fi - echo_yellow "Unable to auto-generate HWID; please enter manually." - elif [[ "${confirm}" = "M" || "${confirm}" = "m" ]]; then - read -rep "Type 'I KNOW WHAT IM DOING' to continue: " confirm - if [[ "${confirm}" != "I KNOW WHAT IM DOING" ]]; then - echo_red "Confirmation phrase not entered; operation cancelled." - return 1 - fi - read -rep "Enter a new HWID (use all caps): " hwid - if [[ -z "${hwid}" ]]; then - echo_red "No HWID entered; operation cancelled." - return 1 + echo_yellow "Unable to auto-generate HWID." >&2 + read -rep "Enter manually instead? [y/N] " confirm + if [[ "${confirm}" = "Y" || "${confirm}" = "y" ]]; then + hwid=$(fixcraft_hwid_manual) || return 1 + echo "${hwid}" + return 0 fi + return 1 + elif [[ "${confirm}" = "M" || "${confirm}" = "m" ]]; then + hwid=$(fixcraft_hwid_manual) || return 1 echo "${hwid}" return 0 fi From f36be7fc6ea88cfec7bf80b706b90061bd076dac Mon Sep 17 00:00:00 2001 From: F1xGOD FWS Date: Wed, 21 Jan 2026 01:54:39 -0600 Subject: [PATCH 04/10] GG --- firmware.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/firmware.sh b/firmware.sh index 532e972..cebe86f 100644 --- a/firmware.sh +++ b/firmware.sh @@ -1477,7 +1477,7 @@ function fixcraft_hwid_select_predefined() { py_bin=$(fixcraft_find_python) || { echo_yellow "Python not found; skipping pre-defined IDs." >&2; return 3; } - lines=$("$py_bin" - "$db_file" "$board" <<'PY') + lines=$("$py_bin" - "$db_file" "$board" <<'PY' import json import sys @@ -1520,6 +1520,7 @@ for i, (hwid, valid, allegation) in enumerate(items, 1): rec = 1 if (i - 1) == best_idx else 0 print(f"{i}|{hwid}|{valid}|{allegation}|{rec}") PY +) status=$? if [[ $status -eq 1 ]]; then return 1 From d045e4d2bb4fe7f99d307fd9b44989fd58ce4c53 Mon Sep 17 00:00:00 2001 From: F1xGOD FWS Date: Wed, 21 Jan 2026 01:58:52 -0600 Subject: [PATCH 05/10] GG --- firmware.sh | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/firmware.sh b/firmware.sh index cebe86f..0dac0a9 100644 --- a/firmware.sh +++ b/firmware.sh @@ -1477,31 +1477,23 @@ function fixcraft_hwid_select_predefined() { py_bin=$(fixcraft_find_python) || { echo_yellow "Python not found; skipping pre-defined IDs." >&2; return 3; } - lines=$("$py_bin" - "$db_file" "$board" <<'PY' -import json -import sys - + lines=$("$py_bin" -c 'import json,sys if len(sys.argv) < 3: sys.exit(3) - db_file = sys.argv[1] board = sys.argv[2] - try: with open(db_file, "r", encoding="utf-8") as fh: data = json.load(fh) except Exception: sys.exit(3) - entries = data.get("devices", {}).get(board, []) items = [] - def to_float(val, default): try: return float(val) except Exception: return default - for entry in entries: if not isinstance(entry, dict): continue @@ -1511,16 +1503,12 @@ for entry in entries: valid = to_float(entry.get("confidence_valid", 1.0), 1.0) allegation = to_float(entry.get("confidence_allegation", 1.0), 1.0) items.append((hwid, valid, allegation)) - if not items: sys.exit(1) - best_idx = min(range(len(items)), key=lambda i: (items[i][2], -items[i][1], i)) for i, (hwid, valid, allegation) in enumerate(items, 1): rec = 1 if (i - 1) == best_idx else 0 - print(f"{i}|{hwid}|{valid}|{allegation}|{rec}") -PY -) + print(f\"{i}|{hwid}|{valid}|{allegation}|{rec}\")' "$db_file" "$board") status=$? if [[ $status -eq 1 ]]; then return 1 From 63e45a1e7078f110187736074f2ba338b808625c Mon Sep 17 00:00:00 2001 From: F1xGOD FWS Date: Wed, 21 Jan 2026 02:03:33 -0600 Subject: [PATCH 06/10] GG --- firmware.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware.sh b/firmware.sh index 0dac0a9..e9decb2 100644 --- a/firmware.sh +++ b/firmware.sh @@ -1508,7 +1508,7 @@ if not items: best_idx = min(range(len(items)), key=lambda i: (items[i][2], -items[i][1], i)) for i, (hwid, valid, allegation) in enumerate(items, 1): rec = 1 if (i - 1) == best_idx else 0 - print(f\"{i}|{hwid}|{valid}|{allegation}|{rec}\")' "$db_file" "$board") + print("{}|{}|{}|{}|{}".format(i, hwid, valid, allegation, rec))' "$db_file" "$board") status=$? if [[ $status -eq 1 ]]; then return 1 From 66388c838449aba0ab7b61aaba77616f6532d3ca Mon Sep 17 00:00:00 2001 From: F1xGOD FWS Date: Wed, 21 Jan 2026 19:03:43 -0600 Subject: [PATCH 07/10] GG --- firmware.sh | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 95 insertions(+), 3 deletions(-) diff --git a/firmware.sh b/firmware.sh index e9decb2..37b93b5 100644 --- a/firmware.sh +++ b/firmware.sh @@ -1568,17 +1568,109 @@ function fixcraft_hwid_lookup_predefined() { ' "${db_file}" } +function fixcraft_hwid_rand_digit() { + printf '%d' $((RANDOM % 10)) +} + +function fixcraft_hwid_rand_letter() { + local letters="ABCDEFGHIJKLMNOPQRSTUVWXYZ" + printf '%s' "${letters:RANDOM%26:1}" +} + +function fixcraft_hwid_rand_alnum() { + local chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + printf '%s' "${chars:RANDOM%36:1}" +} + +function fixcraft_hwid_gen_group() { + local tmpl="$1" + local out="" + local i="" + local ch="" + + for ((i=0; i<${#tmpl}; i++)); do + ch="${tmpl:i:1}" + if [[ "${ch}" =~ [0-9] ]]; then + out+=$(fixcraft_hwid_rand_digit) + elif [[ "${ch}" =~ [A-Z] ]]; then + out+=$(fixcraft_hwid_rand_letter) + else + out+=$(fixcraft_hwid_rand_alnum) + fi + done + + if [[ -z "${out}" ]]; then + out="$(fixcraft_hwid_rand_alnum)$(fixcraft_hwid_rand_alnum)$(fixcraft_hwid_rand_alnum)" + fi + + printf '%s' "${out}" +} + +function fixcraft_hwid_generate_fallback() { + local board="$1" + local template="$2" + local groups_str="" + local groups=() + local prefix_len=2 + local out_groups=() + local i="" + + board=$(printf '%s' "${board}" | tr '[:lower:]' '[:upper:]') + + if [[ -n "${template}" ]]; then + if [[ "${template}" == *" "* ]]; then + groups_str="${template#* }" + fi + fi + + if [[ -n "${groups_str}" ]]; then + IFS='-' read -r -a groups <<< "${groups_str}" + fi + + if [[ ${#groups[@]} -eq 0 ]]; then + groups=("A0Z" "A0Z" "A0Z" "A0Z") + prefix_len=0 + elif (( prefix_len > ${#groups[@]} )); then + prefix_len=${#groups[@]} + fi + + for ((i=0; i<${#groups[@]}; i++)); do + if (( i < prefix_len )); then + out_groups+=("${groups[i]}") + else + out_groups+=("$(fixcraft_hwid_gen_group "${groups[i]}")") + fi + done + + echo "${board} $(IFS=-; echo "${out_groups[*]}")" +} + function fixcraft_hwid_generate() { local board="$1" local script_dir script_dir=$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) local gen_script="${script_dir}/generate-hwid.sh" + local hwid="" + local db_file="" + local template="" - if [[ ! -x "${gen_script}" ]]; then - return 1 + if [[ -x "${gen_script}" ]]; then + hwid=$("${gen_script}" --board "${board}") || true + if [[ -n "${hwid}" ]]; then + echo "${hwid}" + return 0 + fi + fi + + db_file=$(fixcraft_hwid_db_path) + if [[ ! -s "${db_file}" ]]; then + db_file=$(fixcraft_hwid_download_db) || true + fi + if [[ -n "${db_file}" && -s "${db_file}" ]]; then + template=$(fixcraft_hwid_lookup_predefined "${db_file}" "${board}") fi - "${gen_script}" --board "${board}" + fixcraft_hwid_generate_fallback "${board}" "${template}" } function fixcraft_hwid_manual() { From e11322d7b665c3bba0035498a13315ac1f6d2a32 Mon Sep 17 00:00:00 2001 From: F1xGOD FWS Date: Wed, 21 Jan 2026 19:21:57 -0600 Subject: [PATCH 08/10] final --- firmware.sh | 134 ++++++++++++++++----------- generate-hwid.sh | 234 ++++++++++++++++++++++++++++------------------- 2 files changed, 220 insertions(+), 148 deletions(-) diff --git a/firmware.sh b/firmware.sh index 37b93b5..f470bae 100644 --- a/firmware.sh +++ b/firmware.sh @@ -1428,18 +1428,6 @@ function fixcraft_hwid_db_path() { echo "${script_dir}/database/cros-hwid.json" } -function fixcraft_find_python() { - if command -v python3 >/dev/null 2>&1; then - echo "python3" - return 0 - fi - if command -v python >/dev/null 2>&1; then - echo "python" - return 0 - fi - return 1 -} - function fixcraft_hwid_download_db() { local url="https://www.fixcraft.jp/database/cros-hwid.json" local out="/tmp/fixcraft-cros-hwid.json" @@ -1471,45 +1459,57 @@ function fixcraft_hwid_download_db() { function fixcraft_hwid_select_predefined() { local db_file="$1" local board="$2" - local py_bin="" local lines="" local status=0 - py_bin=$(fixcraft_find_python) || { echo_yellow "Python not found; skipping pre-defined IDs." >&2; return 3; } - - lines=$("$py_bin" -c 'import json,sys -if len(sys.argv) < 3: - sys.exit(3) -db_file = sys.argv[1] -board = sys.argv[2] -try: - with open(db_file, "r", encoding="utf-8") as fh: - data = json.load(fh) -except Exception: - sys.exit(3) -entries = data.get("devices", {}).get(board, []) -items = [] -def to_float(val, default): - try: - return float(val) - except Exception: - return default -for entry in entries: - if not isinstance(entry, dict): - continue - hwid = entry.get("hwid") - if not hwid: - continue - valid = to_float(entry.get("confidence_valid", 1.0), 1.0) - allegation = to_float(entry.get("confidence_allegation", 1.0), 1.0) - items.append((hwid, valid, allegation)) -if not items: - sys.exit(1) -best_idx = min(range(len(items)), key=lambda i: (items[i][2], -items[i][1], i)) -for i, (hwid, valid, allegation) in enumerate(items, 1): - rec = 1 if (i - 1) == best_idx else 0 - print("{}|{}|{}|{}|{}".format(i, hwid, valid, allegation, rec))' "$db_file" "$board") - status=$? + lines=$(awk -v board="$board" ' + BEGIN { + in_block=0 + count=0 + } + $0 ~ "\"" board "\"[[:space:]]*:[[:space:]]*\\[" { in_block=1; next } + in_block { + if ($0 ~ /"hwid"[[:space:]]*:/) { + hwid=$0 + sub(/.*"hwid"[[:space:]]*:[[:space:]]*"/, "", hwid) + sub(/".*/, "", hwid) + valid=1 + allegation=1 + } else if ($0 ~ /"confidence_valid"[[:space:]]*:/) { + val=$0 + sub(/.*"confidence_valid"[[:space:]]*:[[:space:]]*/, "", val) + sub(/[^0-9.].*/, "", val) + if (val != "") valid=val+0 + } else if ($0 ~ /"confidence_allegation"[[:space:]]*:/) { + val=$0 + sub(/.*"confidence_allegation"[[:space:]]*:[[:space:]]*/, "", val) + sub(/[^0-9.].*/, "", val) + if (val != "") allegation=val+0 + } + if ($0 ~ /}/ && hwid != "") { + count++ + hwid_arr[count]=hwid + valid_arr[count]=valid+0 + allegation_arr[count]=allegation+0 + hwid="" + } + if ($0 ~ /]/) { exit } + } + END { + if (count == 0) exit 1 + best=1 + for (i=2; i<=count; i++) { + if (allegation_arr[i] < allegation_arr[best] || (allegation_arr[i] == allegation_arr[best] && valid_arr[i] > valid_arr[best])) { + best=i + } + } + for (i=1; i<=count; i++) { + rec = (i == best) ? 1 : 0 + printf "%d|%s|%s|%s|%d\n", i, hwid_arr[i], valid_arr[i], allegation_arr[i], rec + } + } + ' "$db_file") || status=$? + status=${status:-0} if [[ $status -eq 1 ]]; then return 1 fi @@ -1517,7 +1517,6 @@ for i, (hwid, valid, allegation) in enumerate(items, 1): echo_yellow "Unable to read FixCraft database; skipping pre-defined IDs." >&2 return 3 fi - echo "Pick an HWID:" >&2 while IFS='|' read -r idx hwid valid allegation rec; do [[ -z "${idx}" || -z "${hwid}" ]] && continue @@ -1577,6 +1576,16 @@ function fixcraft_hwid_rand_letter() { printf '%s' "${letters:RANDOM%26:1}" } +function fixcraft_hwid_rand_hex_letter() { + local letters="ABCDEF" + printf '%s' "${letters:RANDOM%6:1}" +} + +function fixcraft_hwid_rand_hex() { + local chars="0123456789ABCDEF" + printf '%s' "${chars:RANDOM%16:1}" +} + function fixcraft_hwid_rand_alnum() { local chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" printf '%s' "${chars:RANDOM%36:1}" @@ -1587,20 +1596,37 @@ function fixcraft_hwid_gen_group() { local out="" local i="" local ch="" + local hex_only=0 + + if [[ "${tmpl}" =~ ^[0-9A-F]+$ ]]; then + hex_only=1 + fi for ((i=0; i<${#tmpl}; i++)); do ch="${tmpl:i:1}" if [[ "${ch}" =~ [0-9] ]]; then out+=$(fixcraft_hwid_rand_digit) elif [[ "${ch}" =~ [A-Z] ]]; then - out+=$(fixcraft_hwid_rand_letter) + if (( hex_only )); then + out+=$(fixcraft_hwid_rand_hex_letter) + else + out+=$(fixcraft_hwid_rand_letter) + fi else - out+=$(fixcraft_hwid_rand_alnum) + if (( hex_only )); then + out+=$(fixcraft_hwid_rand_hex) + else + out+=$(fixcraft_hwid_rand_alnum) + fi fi done if [[ -z "${out}" ]]; then - out="$(fixcraft_hwid_rand_alnum)$(fixcraft_hwid_rand_alnum)$(fixcraft_hwid_rand_alnum)" + if (( hex_only )); then + out="$(fixcraft_hwid_rand_hex)$(fixcraft_hwid_rand_hex)$(fixcraft_hwid_rand_hex)" + else + out="$(fixcraft_hwid_rand_alnum)$(fixcraft_hwid_rand_alnum)$(fixcraft_hwid_rand_alnum)" + fi fi printf '%s' "${out}" @@ -1782,7 +1808,9 @@ function set_hwid() Changing this is not normally needed, and if you mess it up, MrChromebox is not going to help you fix it. This won't let you run a different/newer version of ChromeOS. -Proceed at your own risk." +Proceed at your own risk. +P.S. using a pre-defined HWID may allow updates +to work correctly." read -rep "Really change your HWID? [y/N] " confirm [[ "$confirm" = "Y" || "$confirm" = "y" ]] || return diff --git a/generate-hwid.sh b/generate-hwid.sh index ea05c2f..5d59c94 100755 --- a/generate-hwid.sh +++ b/generate-hwid.sh @@ -32,101 +32,145 @@ board=$(printf '%s' "$board" | tr '[:lower:]' '[:upper:]') script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) data_file="$script_dir/database/cros-hwid.json" -py_bin="" -if command -v python3 >/dev/null 2>&1; then - py_bin="python3" -elif command -v python >/dev/null 2>&1; then - py_bin="python" -else - echo "Error: python3 (or python) is required to run this script." >&2 +if [[ ! -s "${data_file}" ]]; then + echo "Error: database file not found: ${data_file}" >&2 + exit 1 +fi + +get_hwids_for_board() { + awk -v board="$board" ' + $0 ~ "\"" board "\"[[:space:]]*:[[:space:]]*\\[" { in_block=1; next } + in_block && /"hwid"[[:space:]]*:/ { + hwid=$0 + sub(/.*"hwid"[[:space:]]*:[[:space:]]*"/, "", hwid) + sub(/".*/, "", hwid) + if (hwid != "") print hwid + } + in_block && /]/ { exit } + ' "${data_file}" +} + +get_all_hwids() { + awk ' + /"hwid"[[:space:]]*:/ { + hwid=$0 + sub(/.*"hwid"[[:space:]]*:[[:space:]]*"/, "", hwid) + sub(/".*/, "", hwid) + if (hwid != "") print hwid + } + ' "${data_file}" +} + +rand_digit() { + printf '%d' $((RANDOM % 10)) +} + +rand_letter() { + local letters="ABCDEFGHIJKLMNOPQRSTUVWXYZ" + printf '%s' "${letters:RANDOM%26:1}" +} + +rand_hex_letter() { + local letters="ABCDEF" + printf '%s' "${letters:RANDOM%6:1}" +} + +rand_hex() { + local chars="0123456789ABCDEF" + printf '%s' "${chars:RANDOM%16:1}" +} + +rand_alnum() { + local chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + printf '%s' "${chars:RANDOM%36:1}" +} + +gen_group() { + local tmpl="$1" + local out="" + local i="" + local ch="" + local hex_only=0 + + if [[ "${tmpl}" =~ ^[0-9A-F]+$ ]]; then + hex_only=1 + fi + + for ((i=0; i<${#tmpl}; i++)); do + ch="${tmpl:i:1}" + if [[ "${ch}" =~ [0-9] ]]; then + out+=$(rand_digit) + elif [[ "${ch}" =~ [A-Z] ]]; then + if (( hex_only )); then + out+=$(rand_hex_letter) + else + out+=$(rand_letter) + fi + else + if (( hex_only )); then + out+=$(rand_hex) + else + out+=$(rand_alnum) + fi + fi + done + + if [[ -z "${out}" ]]; then + if (( hex_only )); then + out="$(rand_hex)$(rand_hex)$(rand_hex)" + else + out="$(rand_alnum)$(rand_alnum)$(rand_alnum)" + fi + fi + + printf '%s' "${out}" +} + +hwids=() +while IFS= read -r line; do + [[ -n "${line}" ]] && hwids+=("${line}") +done < <(get_hwids_for_board) + +if [[ ${#hwids[@]} -eq 0 ]]; then + echo "Board unsupported, trying random" >&2 + while IFS= read -r line; do + [[ -n "${line}" ]] && hwids+=("${line}") + done < <(get_all_hwids) +fi + +if [[ ${#hwids[@]} -eq 0 ]]; then + echo "Error: no HWIDs available in database." >&2 exit 1 fi -"$py_bin" - "$data_file" "$board" <<'PY' -import json -import random -import sys - -if len(sys.argv) < 3: - print("Usage: generate-hwid.sh --board BOARD", file=sys.stderr) - sys.exit(1) - -db_file = sys.argv[1] -board = sys.argv[2] - -with open(db_file, "r", encoding="utf-8") as fh: - data = json.load(fh) - -devices = data.get("devices", {}) - -def parse_groups(hwid): - if not hwid: - return [] - parts = str(hwid).split(" ") - if len(parts) < 2: - return [] - return [g for g in "-".join(parts[1:]).split("-") if g] - -def flatten_entries(device_map): - all_entries = [] - for entries in device_map.values(): - if not isinstance(entries, list): - continue - for entry in entries: - if isinstance(entry, dict) and entry.get("hwid"): - all_entries.append(entry) - return all_entries - -def char_pattern(group): - hex_only = True - pattern = [] - for ch in group: - if "0" <= ch <= "9": - pattern.append("D") - elif "A" <= ch <= "Z": - pattern.append("A") - else: - pattern.append("X") - if not (("0" <= ch <= "9") or ("A" <= ch <= "F")): - hex_only = False - return "".join(pattern), hex_only - -def gen_char(char_type, hex_only): - if char_type == "D": - return str(random.randrange(10)) - if char_type == "A": - letters = "ABCDEF" if hex_only else "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - return random.choice(letters) - pool = "0123456789ABCDEF" if hex_only else "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" - return random.choice(pool) - -def gen_group_from_template(group): - pattern, hex_only = char_pattern(group) - if not pattern: - return "" - return "".join(gen_char(t, hex_only) for t in pattern) - -entries = devices.get(board) -pool = entries if isinstance(entries, list) else None -if not pool: - print("Board unsupported, trying random", file=sys.stderr) - pool = flatten_entries(devices) - -groups = [] -if pool: - template = random.choice(pool) - groups = parse_groups(template.get("hwid")) - -group_count = len(groups) or 4 -prefix_len = min(2, group_count) -out_groups = [] - -for i in range(group_count): - if i < prefix_len and i < len(groups) and groups[i]: - out_groups.append(groups[i]) - continue - template_group = groups[i] if i < len(groups) and groups[i] else "A0Z" - out_groups.append(gen_group_from_template(template_group)) - -print(f"{board} {'-'.join(out_groups)}") -PY +template="${hwids[RANDOM % ${#hwids[@]}]}" +groups_str="" +if [[ "${template}" == *" "* ]]; then + groups_str="${template#* }" +fi + +groups=() +if [[ -n "${groups_str}" ]]; then + IFS='-' read -r -a groups <<< "${groups_str}" +fi + +if [[ ${#groups[@]} -eq 0 ]]; then + groups=("A0Z" "A0Z" "A0Z" "A0Z") + prefix_len=0 +else + prefix_len=2 + if (( prefix_len > ${#groups[@]} )); then + prefix_len=${#groups[@]} + fi +fi + +out_groups=() +for ((i=0; i<${#groups[@]}; i++)); do + if (( i < prefix_len )); then + out_groups+=("${groups[i]}") + else + out_groups+=("$(gen_group "${groups[i]}")") + fi +done + +echo "${board} $(IFS=-; echo "${out_groups[*]}")" From 1f61f6c6a34b04765a8999647de53177a7d28bcb Mon Sep 17 00:00:00 2001 From: F1xGOD FWS Date: Wed, 21 Jan 2026 19:29:25 -0600 Subject: [PATCH 09/10] disclaim --- firmware.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/firmware.sh b/firmware.sh index f470bae..9cdc799 100644 --- a/firmware.sh +++ b/firmware.sh @@ -1716,6 +1716,11 @@ function fixcraft_hwid_manual() { echo "${hwid}" } +function fixcraft_hwid_disclaimer() { + echo_yellow "FixCraft, Inc. provides hardware IDs AS IS with no warranty." >&2 + echo_yellow "Use at your own risk; no guarantees of fitness or support." >&2 +} + function select_new_hwid() { local current_hwid="$1" local board="" @@ -1751,6 +1756,7 @@ function select_new_hwid() { if [[ -s "${db_file}" ]]; then hwid=$(fixcraft_hwid_select_predefined "${db_file}" "${board}") || status=$? if [[ -n "${hwid}" ]]; then + fixcraft_hwid_disclaimer echo "${hwid}" return 0 fi @@ -1760,6 +1766,7 @@ function select_new_hwid() { echo_yellow "looks like your device isnt in the FixCraft Database!" >&2 hwid=$(fixcraft_hwid_generate "${board}") || true if [[ -n "${hwid}" ]]; then + fixcraft_hwid_disclaimer echo "${hwid}" return 0 fi @@ -1771,6 +1778,7 @@ function select_new_hwid() { if [[ "${confirm}" = "A" || "${confirm}" = "a" ]]; then hwid=$(fixcraft_hwid_generate "${board}") || true if [[ -n "${hwid}" ]]; then + fixcraft_hwid_disclaimer echo "${hwid}" return 0 fi From de5978ca8681861d343406a0afa4f87a9146ef45 Mon Sep 17 00:00:00 2001 From: F1xGOD FWS Date: Wed, 21 Jan 2026 19:33:53 -0600 Subject: [PATCH 10/10] disclaim-fix --- firmware.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware.sh b/firmware.sh index 9cdc799..a228912 100644 --- a/firmware.sh +++ b/firmware.sh @@ -1814,8 +1814,8 @@ function set_hwid() echo_yellow "Are you sure you know what you're doing here? Changing this is not normally needed, and if you mess it up, -MrChromebox is not going to help you fix it. This won't let -you run a different/newer version of ChromeOS. +MrChromebox is not going to help you fix it. +* This won't let you run a different/newer version of ChromeOS. Proceed at your own risk. P.S. using a pre-defined HWID may allow updates to work correctly."