V1.1.1
⚡ IoT Firmware Loader (MiraV3)
Công cụ desktop dùng để scan, phát hiện và flash firmware hàng loạt cho các thiết bị OpenWrt (qua giao diện LuCI) trong mạng LAN.
Tech stack: Python 3.9+ · PyQt6 · Scapy · Requests · PyInstaller
📁 Cấu trúc dự án
iot_fw_loader/
├── main.py # UI chính (PyQt6)
├── core/ # Các thành phần cốt lõi và xử lý đa luồng
│ ├── workers.py # Quản lý luồng dùng chung (ScanThread, FlashThread)
│ ├── scanner.py # Quét thiết bị mạng đa lớp (Ping sweep + ARP + Scapy)
│ ├── flasher.py # Flash firmware và tự động hóa qua OpenWrt LuCI bằng API
│ └── ssh_flasher.py # Load/Update firmware qua đường dẫn SSH
├── ui/ # Các component thiết kế giao diện
│ ├── components.py # Custom Qt Widgets (CollapsibleGroupBox, etc.)
│ └── styles.py # Các cấu hình Stylesheet
├── utils/ # Các hàm helper tiện ích
│ ├── network.py # Các hàm xử lý IP, Hostname
│ └── system.py # Các hàm lấy thông tin máy và resources
├── run.sh # Script khởi chạy (macOS/Linux)
├── run.bat # Script khởi chạy (Windows)
├── build_windows.bat # Script đóng gói thành file .exe độc lập (Windows)
└── venv/ # Python virtual environment (tự tạo)
🔧 Cài đặt & Chạy
Yêu cầu
- Python 3.9+
- Các thư viện:
PyQt6,scapy,requests,pyinstaller(để build). - Trên Windows: Cần cài đặt Npcap để
scapycó thể quét ARP ở chế độ sâu (không bắt buộc, có fallback dự phòng).
Khởi chạy nhanh (Môi trường Dev)
macOS / Linux:
./run.sh
Windows:
run.bat
Script tự tạo
venvvà cài dependencies nếu chưa có.
📦 Build ra file chạy độc lập (.exe) cho Windows
Chạy script sau để tự động đóng gói ứng dụng thành 1 file .exe duy nhất (không cần cài Python trên máy đích):
build_windows.bat
File nhận được sẽ nằm ở: dist\IoT_Firmware_Loader.exe.
🏗 Kiến trúc hệ thống
┌─────────────────────────────────────────────────────────────┐
│ main.py (UI) │
│ ┌───────────┐ ┌───────────┐ ┌────────────────────────────┐ │
│ │ Machine │ │ Firmware │ │ Network Scan (QThread) │ │
│ │ Info │ │ Selector │ │ Tham số: Network (CIDR) │ │
│ └───────────┘ └───────────┘ └────────┬───────────────────┘ │
│ ┌────────────────────────────────────┼───────────────────┐ │
│ │ Device Table │ │ │
│ │ [ ] IP │ Name │ MAC │ Status │ │ │
│ │ (Hỗ trợ lọc ẩn Gateway & Self) │ │ │
│ └────────────────────────────────────┼───────────────────┘ │
│ ┌────────────────────────────────────┼───────────────────┐ │
│ │ Flash Controls + Progress Bar │ │ │
│ │ (ThreadPoolExecutor) │ │ │
│ └────────────────────────────────────┼───────────────────┘ │
└───────────────────────────────────────┼─────────────────────┘
│
┌───────────────────┼───────────────────┐
│ │
┌─────▼─────┐ ┌─────▼─────┐
│ scanner.py│ │ flasher.py│
│ │ │ │
│ 1. Ping │ │ LuCI HTTP │
│ Sweep │ │ /cgi-bin/ │
│ 2. arp -a │ │ luci │
│ 3. Scapy │ │ │
└───────────┘ └───────────┘
🔄 Luồng hoạt động chi tiết
1. Quét mạng (Network Scan)
Module scanner.py sử dụng chiến lược 3 lớp để đảm bảo phát hiện đa dạng các thiết bị mạng mà vẫn duy trì khả năng tránh spam/lag cho OS:
- Ping Sweep: Gửi gói tin Ping song song (tối đa 50 threads) để đánh thức thiết bị và điền IP/MAC vào bảng ARP Cache của hệ điều hành.
- ARP Table Fallback: Đọc bảng ARP nội bộ của OS (
arp -a) bằng Regex. Hoạt động đa nền tảng (Windows/macOS/Linux) mà không cần quyền Admin/Root. - Scapy ARP (Tính năng nâng cao): Gửi các gói tin ARP Broadcast trực tiếp để đảm bảo bao phủ gap nếu có. Yêu cầu quyền Root trên Linux/macOS hoặc Npcap trên Windows.
Ngoài ra, công cụ tự động dò Hostname (
socket.gethostbyaddr) song song để lấy tên thiết bị.
2. Giao diện thiết bị (Device Table)
- Thiết bị được thu thập sẽ hiện ra trên UI dạng bảng, với tính năng tuỳ chọn hiển thị (checkbox ẩn Gateway mạng hiện tại và chính máy tính đang quét phần mềm).
- Trạng thái các luồng UI được tách rời bằng QThread + QPropertyAnimation cho hộp Collapsible nhằm tự động cuộn khi ẩn hiện nội dung, không làm treo ứng dụng.
3. Nạp Firmware (OpenWrt Flasher)
Từ phiên bản hiện tại, phương thức ESP32 OTA không còn được áp dụng, thay vào đó module flasher.py tự động hóa quá trình update của router OpenWrt (Barrier Breaker 14.07):
- Bước 1: Gửi
POSTchứa thông tin đăng nhập (username, password mặc định là root/trống, hoặc luci_username tuỳ thuộc firmware) để lấy session cookiestok. - Bước 2: Đẩy file firmware
*.bindạngmultipart/form-datalên/cgi-bin/luci/;stok=.../admin/system/flashops. - Bước 3: Gửi lệnh tiếp tục (Kèm tuỳ chọn giữ cấu hình
keep=onnếu có). - Bước 4: Thiết bị xác nhận và tự khởi động lại. Cập nhật Status trên Application.
- 🛠 Hỗ trợ
ThreadPoolExecutorđể Flash đồng thời nhiều thiết bị, với lựa chọn số luồng đồng thời tuỳ chỉnh.
⚙️ Cấu hình
| Tham số | Mô tả |
|---|---|
| Network | Dải mạng quét (vd: 192.168.1.0/24). Tự động tính từ local IP app. |
| Show all | Tuỳ chọn cho phép liệt kê cả Gateway IP máy chủ. |
| Concurrent devices | Số luồng để đĩa flash song song. 0 = Không giới hạn. |
| Firmware filter | Mặc định hiển thị và hỗ trợ .bin, .hex, .uf2. |
🔒 Lưu ý bảo mật & Quyền
- Quyền Scanner: Ở chế độ quét Scapy (Sâu), cần khởi chạy bằng quyền Admin (Windows) hoặc Sudo (macOS/Linux), tuy nhiên App có thể chạy kể cả không có quyền Admin nhờ chiến lược Ping Sweep +
arp -a. - Ẩn Console (Window): Khi gọi subproces (
ping,arp), ứng dụng có tích hợp thuộc tính platformCREATE_NO_WINDOWđể ngăn chặn các terminal đen giật nháy trên màn hình Windows. - Bảo mật mạng: Quá trình tải firmware lên thiết bị thông qua HTTP thuần, chỉ nên sử dụng ở mạng LAN nội bộ, tránh những mạng mở hoặc public để tránh lộ file firmware.
- LuCI Login: API này nhắm thẳng vào quá trình đăng nhập qua form, nên sẽ tự động handle các router đang dùng OpenWrt Barrier Breaker mà không cần phải can thiệp tay.
Description
V1.2.3
Latest
Languages
Python
98.2%
Batchfile
1.5%
Shell
0.3%