最近公司有一個專案,其中一部分的內容需要將一款巨集鍵盤操作修改成特定內容
由於這些巨集鍵盤必須使用特定軟體才能修改內容,而且這個軟體只能透過滑鼠點擊來操作
如果只是十多個要修改還可以手動修改,但如果是數千個要手動修改會非常耗時
而且出錯率會很高,檢查時也非常困難
因此,我們需要想辦法將操作自動化,或至少能夠半自動化
鍵盤外觀
一款藍牙巨集鍵盤,共有 6個鍵盤按鈕 及 1個可按壓旋扭
可以使用 USB Type-C 差電 及 連接到電腦設定巨集內容
電源開關按鈕
階層切換按鈕,這款巨集鍵盤能保存多種按鍵模式
修改軟件
修改巨集鍵盤的按鈕、旋扭內容需要使用指定軟件
當連接 巨集鍵盤 後,軟件會自動偵測到鍵盤的類型
然後便可以設定指定按鈕、旋扭或操作
設定內容後,按 Download 便會修改巨集鍵盤的內容
監察資料
尋找裝置
雖然 巨集鍵盤 能在任意系統上使用,但修改軟件卻只提供 Windows 及 Mac OS 的版本,無法在 Linux 上使用
如果需要修改內容,仍然需要使用 Windows 或 Mac OS
在下估計,這類裝置都是透過 宿主系統 向 USB裝置 發送特定資料來修改操作內容
因此在下認為只要知道這些資料,理論上便能夠在 Linux 上,甚至在其他系統發送相同資料來修改 巨集鍵盤 的內容
由於在下不確定 巨集鍵盤 接收到甚麼資料來修改內容,因此將連接到電腦前後,都在 Terminal 輸入
ls "/dev"
比較連接到電腦前後的差異,發現 /dev/hidraw 的數量有分別,即是 巨集鍵盤 屬於 hidraw
因此在下再輸入
dmesg | grep -i "usb" | grep -i "hidraw" lsusb
獲得 巨集鍵盤 的 hidraw, bus 及 device 的 編號
在下使用 Wireshark 來擷取 USB 的資料,輸入
sudo apt install wireshark
安裝後,輸入
sudo modprobe usbmon sudo wireshark
啟動 usbmon模組 來監察 USB 資料
而由於 usbmon模組 需要 root 或 sudo user 才能監察 USB 資料,因此以 sudo 啟動 Wireshark
使用Wireshark
以 root 或 super user 啟動 Wireshark ,才可以顯 usbmon 的選項
usbmon0 是監察所有 USB 的資料,而大於 0 的 usbmon 則是監察對應 USB BUS 的資料
例如使用 lsusb 顯示 USB 裝置位於 bus 1 即是能夠使用 usbmon1 監察
因此使用指定 usbmon 比較節省系統資源
不過即使使用指定 usbmon 監察 USB 資料,仍然會監察到大量資料
過濾資料
Wireshark 能使用類似 C 的 判斷式 將資料過濾,只顯示需要的資料,在文字爛輸入
usb.device_address == ?
usb.device_address 可以過濾符合 lsusb 的 device 編號並只顯示該 USB 裝置的資料
既然能夠使用類似 C 的判斷式語法來過濾資料
除了 == (等於) 、 亦可以使用 != (不等於) 、 < (小於) 、 >= (大於或等於) 等比較方式
使用虛擬機
由於修改資料軟件不支援 Linux ,因此在下仍然需要在 Windows 測試
在下在 VirtualBox 運行 Windows虛擬機 ,並讓 虛擬機 存取 USB裝置
完成設定後,便可以讓 宿主系統 的 Wireshark 監察被 虛擬機 存取的 USB 裝置
然而當修改軟件開啟後,由於軟件會不斷偵測 巨集鍵盤 的狀態或類型等資料
因此不斷監察到有資料傳輸,同樣會影響監察修改時的資料
所以避免顯示到大量無關的資料,可以使用判斷式將不必要的資料過濾,輸入
usb.device_address == ? && usb.src == "host" && usb.data_len > 0
usb.src 的內容是字串,因此必須使用 " (雙引腳),可以過濾符合資料來源的名稱
usb.data_len 為統計 USB 資料的長度,因為 usb.data_len > 0 可以過濾並只顯示有資料傳輸的項目
擷取資料
當按下 Reading Device 按鈕後, Wireshark 便監察到資料傳輸
然後就是最重要的修改按鈕及旋扭操作的內容
保存資料
當擷取大量資料後,還是需要先保存資料才能分析
到 File > Export Packet Dissertions > As JSON...
設定檔案名後儲存
檔案中會找到 usbhid.data 的資料是一串很長的 十六進制資料,就是傳輸到 USB裝置 的資料
分析資料
既然確定能夠擷取資料,便可以使用類似操作的方式將資料作比較,來推斷出哪一組資料控制哪一個設定
例如 abc.json 測試使用相同按鈕,分別操作為 a鍵 、 b鍵 、 c鍵 ,會發現第12組資料為 04, 05, 06
便能夠推測試 第12組資料是設定按鈕的操作效果,及測試往後的數值代表哪個操作
而當資料為 04 即是操作 a鍵 , 05 即是操作 b鍵 , 06 即是操作 c鍵 ……是要不斷重要測試便可以配對所有 數值 及 操作
但 操作 還有些微區分,例如 modifiers.json 中測試 Ctrl鍵, Shift鍵, Alt鍵, Meta鍵 是 第11組資料
而且資料是 01, 02, 04, 08 的二進制遞增資料 ,這意味著將數值合併便能操作不同按鍵的組合
還可以測試 10, 20, 40, 80 是否還有額外功能
由於要測試的資料太多,因此在下沒有將全部資料都在文章中展示,只將部分資料記錄作例子及說明
詳細資料請查看資料表
修改操作
完整指令
| 偏移 | 位元組長度 | 類型 | 功能 | |
|---|---|---|---|---|
| 十進制 | 十六進制 | |||
| 0 | 0x00 | 1 | 無符號數值 | 標頭,必定是 0x03 |
| 1 | 0x01 | 1 | 無符號數值 | 用途不明,通常修改資料時是 0xFD 或 0xFE |
| 2 | 0x02 | 1 | 無符號數值 | 操作類型
|
| 3 | 0x03 | 1 | 無符號數值 | 選擇層(Layer),由 1 開始的整數 |
| 4 | 0x04 | 1 | 無符號數值 | 按鈕觸發模擬類別
|
| 5 | 0x05 | 2 | 無符號數值 | 延遲(毫秒) 例如要輸入 1000 ,即是 1000 / 256 = 3 餘 232 結果是 0xE8, 0x03 |
| 6 | 0x06 | |||
| 7 | 0x07 | 1 | 用途不明,通常是 0x00 | |
| 8 | 0x08 | 1 | 用途不明,通常是 0x00 | |
| 9 | 0x09 | 1 | 用途不明,通常是 0x00 | |
| 10 | 0x0A | 1 | 無符號數值 | 輸出內容,最多 18 (0x12) |
| 11 | 0x0B | 1 | 無符號數值 | 當 模擬類別 為 0x01 ,第1輸出內容的,參考 修飾鍵 當 模擬類別 為 0x02 , 多媒體控制,參考 特殊鍵 |
| 12 | 0x0C | 1 | 無符號數值 | 當 模擬類別 為 0x01 ,第1輸出內容,參考 一般鍵 當 模擬類別 為 0x03 ,滑鼠按鈕,參考 滑鼠鍵 當 模擬類別 為 0x08 ,LED控制,參考 LED模式及顏色 |
| 13 | 0x0D | 1 | 無符號數值 | 第2輸出內容的修飾鍵,參考 修飾鍵 |
| 14 | 0x0E | 1 | 無符號數值 | 第2輸出內容,參考 一般鍵 |
| 15 | 0x0F | 1 | 無符號數值 | 當 模擬類別 為 0x01 ,第3輸出內容的修飾鍵,參考 修飾鍵 當 模擬類別 為 0x03 ,滑鼠滾輪,參考 滑鼠捲動 |
| 16 | 0x10 | 1 | 無符號數值 | 第3輸出內容,參考 一般鍵 |
| 17 | 0x11 | 1 | 無符號數值 | 第4輸出內容的修飾鍵,參考 修飾鍵 |
| 18 | 0x12 | 1 | 無符號數值 | 第4輸出內容,參考 一般鍵 |
| 19 | 0x13 | 1 | 無符號數值 | 第5輸出內容的修飾鍵,參考 修飾鍵 |
| 20 | 0x14 | 1 | 無符號數值 | 第5輸出內容,參考 一般鍵 |
| 21 | 0x15 | 1 | 無符號數值 | 第6輸出內容的修飾鍵,參考 修飾鍵 |
| 22 | 0x16 | 1 | 無符號數值 | 第6輸出內容,參考 一般鍵 |
| 23 | 0x17 | 1 | 無符號數值 | 第7輸出內容的修飾鍵,參考 修飾鍵 |
| 24 | 0x18 | 1 | 無符號數值 | 第7輸出內容,參考 一般鍵 |
| 25 | 0x19 | 1 | 無符號數值 | 第8輸出內容的修飾鍵,參考 修飾鍵 |
| 26 | 0x1A | 1 | 無符號數值 | 第8輸出內容,參考 一般鍵 |
| 27 | 0x1B | 1 | 無符號數值 | 第9輸出內容的修飾鍵,參考 修飾鍵 |
| 28 | 0x1C | 1 | 無符號數值 | 第9輸出內容,參考 一般鍵 |
| 29 | 0x1D | 1 | 無符號數值 | 第10輸出內容的修飾鍵,參考 修飾鍵 |
| 30 | 0x1E | 1 | 無符號數值 | 第10輸出內容,參考 一般鍵 |
| 31 | 0x1F | 1 | 無符號數值 | 第11輸出內容的修飾鍵,參考 修飾鍵 |
| 32 | 0x20 | 1 | 無符號數值 | 第11輸出內容,參考 一般鍵 |
| 33 | 0x21 | 1 | 無符號數值 | 第12輸出內容的修飾鍵,參考 修飾鍵 |
| 34 | 0x22 | 1 | 無符號數值 | 第12輸出內容,參考 一般鍵 |
| 35 | 0x23 | 1 | 無符號數值 | 第13輸出內容的修飾鍵,參考 修飾鍵 |
| 36 | 0x24 | 1 | 無符號數值 | 第13輸出內容,參考 一般鍵 |
| 37 | 0x25 | 1 | 無符號數值 | 第14輸出內容的修飾鍵,參考 修飾鍵 |
| 38 | 0x26 | 1 | 無符號數值 | 第14輸出內容,參考 一般鍵 |
| 39 | 0x27 | 1 | 無符號數值 | 第15輸出內容的修飾鍵,參考 修飾鍵 |
| 40 | 0x28 | 1 | 無符號數值 | 第15輸出內容,參考 一般鍵 |
| 41 | 0x29 | 1 | 無符號數值 | 第16輸出內容的修飾鍵,參考 修飾鍵 |
| 42 | 0x2A | 1 | 無符號數值 | 第16輸出內容,參考 一般鍵 |
| 43 | 0x2B | 1 | 無符號數值 | 第17輸出內容的修飾鍵,參考 修飾鍵 |
| 44 | 0x2C | 1 | 無符號數值 | 第17輸出內容,參考 一般鍵 |
| 45 | 0x2D | 1 | 無符號數值 | 第18輸出內容的修飾鍵,參考 修飾鍵 |
| 46 | 0x2E | 1 | 無符號數值 | 第18輸出內容,參考 一般鍵 |
| 47 | 0x2F | 1 | 用途不明,通常是 0x00 | |
| 48 | 0x30 | 1 | 用途不明,通常是 0x00 | |
| 49 | 0x31 | 1 | 用途不明,通常是 0x00 | |
| 50 | 0x32 | 1 | 用途不明,通常是 0x00 | |
| 51 | 0x33 | 1 | 用途不明,通常是 0x00 | |
| 52 | 0x34 | 1 | 用途不明,通常是 0x00 | |
| 53 | 0x35 | 1 | 用途不明,通常是 0x00 | |
| 54 | 0x36 | 1 | 用途不明,通常是 0x00 | |
| 55 | 0x37 | 1 | 用途不明,通常是 0x00 | |
| 56 | 0x38 | 1 | 用途不明,通常是 0x00 | |
| 57 | 0x39 | 1 | 用途不明,通常是 0x00 | |
| 58 | 0x3A | 1 | 用途不明,通常是 0x00 | |
| 59 | 0x3B | 1 | 用途不明,通常是 0x00 | |
| 60 | 0x3C | 1 | 用途不明,通常是 0x00 | |
| 61 | 0x3D | 1 | 用途不明,通常是 0x00 | |
| 62 | 0x3E | 1 | 用途不明,通常是 0x00 | |
| 63 | 0x3F | 1 | 用途不明,通常是 0x00 | |
| 64 | 0x40 | 1 | 用途不明,通常是 0x00 | |
修飾鍵
| 數值 | 功能 | |
|---|---|---|
| 十進制 | 十六進制 | |
| 1 | 0x01 | 左Ctrl 或 左Control |
| 2 | 0x02 | 左Shift |
| 4 | 0x04 | 左Alt 或 左Option |
| 8 | 0x08 | 左Meta 或 左Command |
| 16 | 0x10 | 右Ctrl 或 右Control |
| 32 | 0x20 | 右Shift |
| 64 | 0x40 | 右Alt 或 右Option |
| 128 | 0x80 | 右Meta 或 右Command |
一般鍵
| 數值 | 功能 | |
|---|---|---|
| 十進制 | 十六進制 | |
| 0 | 0x00 | 無效 |
| 1 | 0x01 | 用途不明 |
| 2 | 0x02 | 用途不明 |
| 3 | 0x03 | 用途不明 |
| 4 | 0x04 | 小寫字母a鍵 |
| 5 | 0x05 | 小寫字母b鍵 |
| 6 | 0x06 | 小寫字母c鍵 |
| 7 | 0x07 | 小寫字母d鍵 |
| 8 | 0x08 | 小寫字母e鍵 |
| 9 | 0x09 | 小寫字母f鍵 |
| 10 | 0x0A | 小寫字母g鍵 |
| 11 | 0x0B | 小寫字母h鍵 |
| 12 | 0x0C | 小寫字母i鍵 |
| 13 | 0x0D | 小寫字母j鍵 |
| 14 | 0x0E | 小寫字母k鍵 |
| 15 | 0x0F | 小寫字母l鍵 |
| 16 | 0x10 | 小寫字母m鍵 |
| 17 | 0x11 | 小寫字母n鍵 |
| 18 | 0x12 | 小寫字母o鍵 |
| 19 | 0x13 | 小寫字母p鍵 |
| 20 | 0x14 | 小寫字母q鍵 |
| 21 | 0x15 | 小寫字母r鍵 |
| 22 | 0x16 | 小寫字母s鍵 |
| 23 | 0x17 | 小寫字母t鍵 |
| 24 | 0x18 | 小寫字母u鍵 |
| 25 | 0x19 | 小寫字母v鍵 |
| 26 | 0x1A | 小寫字母w鍵 |
| 27 | 0x1B | 小寫字母x鍵 |
| 28 | 0x1C | 小寫字母y鍵 |
| 29 | 0x1D | 小寫字母z鍵 |
| 30 | 0x1E | 數字1鍵 |
| 31 | 0x1F | 數字2鍵 |
| 32 | 0x20 | 數字3鍵 |
| 33 | 0x21 | 數字4鍵 |
| 34 | 0x22 | 數字5鍵 |
| 35 | 0x23 | 數字6鍵 |
| 36 | 0x24 | 數字7鍵 |
| 37 | 0x25 | 數字8鍵 |
| 38 | 0x26 | 數字9鍵 |
| 39 | 0x27 | 數字0鍵 |
| 40 | 0x28 | Enter鍵 |
| 41 | 0x29 | Escape鍵 |
| 42 | 0x2A | Backspace鍵 |
| 43 | 0x2B | Tab鍵 |
| 44 | 0x2C | Space鍵 |
| 45 | 0x2D | 減號鍵 |
| 46 | 0x2E | 等於號鍵 |
| 47 | 0x2F | 開方括號鍵 |
| 48 | 0x30 | 關方括號鍵 |
| 49 | 0x31 | 反斜線鍵 |
| 50 | 0x32 | 反斜線鍵(日) |
| 51 | 0x33 | 分號鍵 |
| 52 | 0x34 | 單引號鍵 |
| 53 | 0x35 | 反引號鍵 |
| 54 | 0x36 | 逗號鍵 |
| 55 | 0x37 | 點鍵 |
| 56 | 0x38 | 斜線鍵 |
| 57 | 0x39 | Caps Lock鍵 |
| 58 | 0x3A | F1鍵 |
| 59 | 0x3B | F2鍵 |
| 60 | 0x3C | F3鍵 |
| 61 | 0x3D | F4鍵 |
| 62 | 0x3E | F5鍵 |
| 63 | 0x3F | F6鍵 |
| 64 | 0x40 | F7鍵 |
| 65 | 0x41 | F8鍵 |
| 66 | 0x42 | F9鍵 |
| 67 | 0x43 | F10鍵 |
| 68 | 0x44 | F11鍵 |
| 69 | 0x45 | F12鍵 |
| 70 | 0x46 | Print Screen鍵 |
| 71 | 0x47 | Scroll Lock鍵 |
| 72 | 0x48 | Pause鍵 |
| 73 | 0x49 | Insert鍵 |
| 74 | 0x4A | Home鍵 |
| 75 | 0x4B | Page Up鍵 |
| 76 | 0x4C | Delete鍵 |
| 77 | 0x4D | End鍵 |
| 78 | 0x4E | Page Down鍵 |
| 79 | 0x4F | 右箭咀鍵 |
| 80 | 0x50 | 左箭咀鍵 |
| 81 | 0x51 | 下箭咀鍵 |
| 82 | 0x52 | 上箭咀鍵 |
| 83 | 0x53 | Num Lock鍵 |
| 84 | 0x54 | NumPad 斜線鍵 |
| 85 | 0x55 | NumPad 星號鍵 |
| 86 | 0x56 | NumPad 減號鍵 |
| 87 | 0x57 | NumPad 加號鍵 |
| 88 | 0x58 | NumPad Enter鍵 |
| 89 | 0x59 | NumPad 數字1鍵 |
| 90 | 0x5A | NumPad 數字2鍵 |
| 91 | 0x5B | NumPad 數字3鍵 |
| 92 | 0x5C | NumPad 數字4鍵 |
| 93 | 0x5D | NumPad 數字5鍵 |
| 94 | 0x5E | NumPad 數字6鍵 |
| 95 | 0x5F | NumPad 數字7鍵 |
| 96 | 0x60 | NumPad 數字8鍵 |
| 97 | 0x61 | NumPad 數字9鍵 |
| 98 | 0x62 | NumPad 數字0鍵 |
| 99 | 0x63 | NumPad 點鍵 |
| 100 | 0x64 | NumPad 小於號鍵 |
| 101 | 0x65 | Context Menu鍵 |
| 102 | 0x66 | Halt鍵 |
| 103 | 0x67 | NumPad 等號鍵 |
| 104 | 0x68 | F13鍵 |
| 105 | 0x69 | F14鍵 |
| 106 | 0x6A | F15鍵 |
| 107 | 0x6B | F16鍵 |
| 108 | 0x6C | F17鍵 |
| 109 | 0x6D | F18鍵 |
| 110 | 0x6E | F19鍵 |
| 111 | 0x6F | F20鍵 |
| 112 | 0x70 | F21鍵 |
| 113 | 0x71 | F22鍵 |
| 114 | 0x72 | F23鍵 |
| 115 | 0x73 | F24鍵 |
| 116 | 0x74 | Execute |
| 117 | 0x75 | Help |
| 118 | 0x76 | Menu |
| 119 | 0x77 | Select |
| 120 | 0x78 | Browser Stop |
| 121 | 0x79 | Redo |
| 122 | 0x7A | Undo |
| 123 | 0x7B | Cut |
| 124 | 0x7C | Copy |
| 125 | 0x7D | Paste |
| 126 | 0x7E | Find |
| 127 | 0x7F | Mute |
| 128 | 0x80 | Volume+ |
| 129 | 0x81 | Volume- |
| 130 | 0x82 | 用途不明 |
| 131 | 0x83 | 用途不明 |
| 132 | 0x84 | 用途不明 |
| 133 | 0x85 | NumPad 逗號鍵 |
| 134 | 0x86 | 用途不明 |
| 135 | 0x87 | Internation1 |
| 136 | 0x88 | Internation2 |
| 137 | 0x89 | Internation3 |
| 138 | 0x8A | Internation4 |
| 139 | 0x8B | Internation5 |
| 140 | 0x8C | Internation6 |
| 141 | 0x8D | Internation7 |
| 142 | 0x8E | Internation8 |
| 143 | 0x8F | Internation9 |
| 144 | 0x90 | Lang1 |
| 145 | 0x91 | Lang2 |
| 146 | 0x92 | Lang3 |
| 147 | 0x93 | Lang4 |
| 148 | 0x94 | Lang5 |
| 149 | 0x95 | Lang6 |
| 150 | 0x96 | Lang7 |
| 151 | 0x97 | Lang8 |
| 152 | 0x98 | Lang9 |
| 153 | 0x99 | 未定義 |
| 154 | 0x9A | 未定義 |
| 155 | 0x9B | 未定義 |
| 156 | 0x9C | NumPad Delete鍵 |
| 157 | 0x9D | 未定義 |
| 158 | 0x9E | SysReg鍵 |
| 159 | 0x9F | Cancel |
| 160 | 0xA0 | Clear |
| 161 | 0xA1 | Prior |
| 162 | 0xA2 | Return |
| 163 | 0xA3 | Separater |
| 164 | 0xA4 | Out |
| 165 | 0xA5 | Oper |
| 166 | 0xA6 | ClearAgain |
| 167 | 0xA7 | CrSelProps |
| 168 | 0xA8 | ExSel |
| 169 | 0xA9 | 未定義 |
| 170 | 0xAA | 未定義 |
| 171 | 0xAB | 未定義 |
| 172 | 0xAC | 未定義 |
| 173 | 0xAD | 未定義 |
| 174 | 0xAE | 未定義 |
| 175 | 0xAF | 未定義 |
| 176 | 0xB0 | NumPad 00鍵 |
| 177 | 0xB1 | NumPad 000鍵 |
| 178 | 0xB2 | NumPad 千位分隔號鍵 |
| 179 | 0xB3 | NumPad 小數點鍵 |
| 180 | 0xB4 | NumPad 貨幣符號鍵 |
| 181 | 0xB5 | NumPad 子貨幣符號鍵 |
| 182 | 0xB6 | NumPad (鍵 |
| 183 | 0xB7 | NumPad )鍵 |
| 184 | 0xB8 | NumPad {鍵 |
| 185 | 0xB9 | NumPad }鍵 |
| 186 | 0xBA | NumPad Tab鍵 |
| 187 | 0xBB | NumPad Backspace鍵 |
| 188 | 0xBC | NumPad A鍵 |
| 189 | 0xBD | NumPad B鍵 |
| 190 | 0xBE | NumPad C鍵 |
| 191 | 0xBF | NumPad D鍵 |
| 192 | 0xC0 | NumPad E鍵 |
| 193 | 0xC1 | NumPad F鍵 |
| 194 | 0xC2 | NumPad XOR鍵 |
| 195 | 0xC3 | NumPad ^鍵 |
| 196 | 0xC4 | NumPad %鍵 |
| 197 | 0xC5 | NumPad <鍵 |
| 198 | 0xC6 | NumPad >鍵 |
| 199 | 0xC7 | NumPad &鍵 |
| 200 | 0xC8 | NumPad &&鍵 |
| 201 | 0xC9 | NumPad |鍵 |
| 202 | 0xCA | NumPad ||鍵 |
| 203 | 0xCB | NumPad :鍵 |
| 204 | 0xCC | NumPad #鍵 |
| 205 | 0xCD | NumPad Space鍵 |
| 206 | 0xCE | NumPad @鍵 |
| 207 | 0xCF | NumPad !鍵 |
| 208 | 0xD0 | NumPad Memory Store鍵 |
| 209 | 0xD1 | NumPad Memory Recall鍵 |
| 210 | 0xD2 | NumPad Memory Clear鍵 |
| 211 | 0xD3 | NumPad Memory Add鍵 |
| 212 | 0xD4 | NumPad Memory Subtract鍵 |
| 213 | 0xD5 | NumPad Memory Mulitple鍵 |
| 214 | 0xD6 | NumPad Memory Division鍵 |
| 215 | 0xD7 | NumPad 正負號鍵 |
| 216 | 0xD8 | NumPad Clear鍵 |
| 217 | 0xD9 | NumPad Clear Entry鍵 |
| 218 | 0xDA | NumPad 二進制鍵 |
| 219 | 0xDB | NumPad 八進制鍵 |
| 220 | 0xDC | NumPad 十進制鍵 |
| 221 | 0xDD | NumPad 十六進制鍵 |
| 222 | 0xDE | 未定義 |
| 223 | 0xDF | 未定義 |
| 224 | 0xE0 | 左Ctrl鍵 / 左Control鍵 |
| 225 | 0xE1 | 左Shift鍵 |
| 226 | 0xE2 | 左Alt鍵 / 左Option鍵 |
| 227 | 0xE3 | 左Meta鍵 / 左Command鍵 |
| 228 | 0xE4 | 右Ctrl鍵 / 右Control鍵 |
| 229 | 0xE5 | 右Shift鍵 |
| 230 | 0xE6 | 右Alt鍵 / 右Option鍵 |
| 231 | 0xE7 | 右Meta鍵 / 右Command鍵 |
| 232 | 0xE8 | Play/Pause鍵 |
| 233 | 0xE9 | 按鍵有效,但不確定用途 |
| 234 | 0xEA | 按鍵有效,但不確定用途 |
| 235 | 0xEB | 按鍵有效,但不確定用途 |
| 236 | 0xEC | Eject鍵 |
| 237 | 0xED | Volume+鍵 |
| 238 | 0xEE | Volume-鍵 |
| 239 | 0xEF | Mute/Unmute鍵 |
| 240 | 0xF0 | Browser Open鍵 |
| 241 | 0xF1 | History Backward鍵 |
| 242 | 0xF2 | History Forward鍵 |
| 243 | 0xF3 | Browser Stop鍵 |
| 244 | 0xF4 | Find鍵 |
| 245 | 0xF5 | 未定義 |
| 246 | 0xF6 | 未定義 |
| 247 | 0xF7 | 未定義 |
| 248 | 0xF8 | Sleep鍵 |
| 249 | 0xF9 | Lock鍵 |
| 250 | 0xFA | Browser Refresh鍵 |
| 251 | 0xFB | Calculator鍵 |
| 252 | 0xFC | 未定義 |
| 253 | 0xFD | 未定義 |
| 254 | 0xFE | 未定義 |
| 255 | 0xFF | 未定義 |
特殊鍵
| 數值 | 功能 | |
|---|---|---|
| 十進制 | 十六進制 | |
| 35 | 0x23 | 瀏覽器首頁 |
| 36 | 0x24 | 瀏覽器上一頁 |
| 37 | 0x25 | 瀏覽器下一頁 |
| 39 | 0x27 | 瀏覽器重新整理 |
| 82 | 0x52 | Bass+ |
| 83 | 0x53 | Bass- |
| 84 | 0x54 | Treble+ |
| 85 | 0x55 | Treble- |
| 111 | 0x6F | 提高熒幕亮度 |
| 112 | 0x70 | 降低熒幕亮度 |
| 131 | 0x83 | 開啟預設多媒體播放器 |
| 138 | 0x8A | 開啟預設電子郵件客戶端 |
| 146 | 0x92 | 開啟預設計算機 |
| 148 | 0x94 | 開啟本機目錄 |
| 181 | 0xB5 | 上一首媒體 |
| 182 | 0xB6 | 下一首媒體 |
| 205 | 0xCD | 播放或暫停 |
| 226 | 0xE2 | 靜音切換 |
| 233 | 0xE9 | 提高播放音量 |
| 234 | 0xEA | 降低播放音量 |
雖然 Bass 及 Treble 是與音樂有關的字詞,但在下仍然無法得知在電腦上的用途
滑鼠鍵
| 數值 | 功能 | |
|---|---|---|
| 十進制 | 十六進制 | |
| 1 | 0x01 | 左鍵 |
| 2 | 0x02 | 右鍵 |
| 4 | 0x04 | 中鍵 |
LED 模式
| 數值 | 功能 | |
|---|---|---|
| 十進制 | 十六進制 | |
| 0 | 0x?0 | 關閉所有LED |
| 1 | 0x?1 | 所有LED指定顏色長亮 |
| 2 | 0x?2 | 操作按鈕時,所有LED順次序亮著指定顏色後關閉 |
| 3 | 0x?3 | 操作按鈕時,所有LED逆次序亮著指定顏色後關閉 |
| 4 | 0x?4 | 操作按鈕時,所有LED亮著指定顏色後關閉 |
| 5 | 0x?5 | 所有LED白光長亮 |
LED 顏色
| 數值 | 功能 | |
|---|---|---|
| 十進制 | 十六進制 | |
| 16 ~ 31 | 0x1? | 紅色 |
| 32 ~ 47 | 0x2? | 橙色 |
| 48 ~ 63 | 0x3? | 黃色 |
| 64 ~ 79 | 0x4? | 綠色 |
| 80 ~ 95 | 0x5? | 青色 |
| 96 ~ 111 | 0x6? | 藍色 |
| 112 ~ 127 | 0x7? | 紫色 |
LED 模式及顏色
| 0x?0 | 0x?1 | 0x?2 | 0x?3 | 0x?4 | 0x?5 | |
|---|---|---|---|---|---|---|
| 0x1? | 0x10 | 0x11 | 0x12 | 0x13 | 0x14 | 0x15 |
| 0x2? | 0x20 | 0x21 | 0x22 | 0x23 | 0x24 | 0x25 |
| 0x3? | 0x30 | 0x31 | 0x32 | 0x33 | 0x34 | 0x35 |
| 0x4? | 0x40 | 0x41 | 0x42 | 0x43 | 0x44 | 0x45 |
| 0x5? | 0x50 | 0x51 | 0x52 | 0x53 | 0x54 | 0x55 |
| 0x6? | 0x60 | 0x61 | 0x62 | 0x63 | 0x64 | 0x65 |
| 0x7? | 0x70 | 0x71 | 0x72 | 0x73 | 0x74 | 0x75 |
透過組合兩組數值,便可以設定不同顏色及模式,例如:
0x11 是 所有LED紅光長亮
0x23 是 操作按鈕時,所有LED順次序亮著黃光後關閉
0x64 是 操作按鈕時,所有LED亮著藍光後關閉
但 0x?0 及 0x?5 是無法設定顏色
滑鼠捲動
| 數值 | 功能 | |
|---|---|---|
| 十進制 | 十六進制 | |
| 1 | 0x01 | 向上捲動 |
| 255 | 0xFF | 向下捲動 |
根據在下判斷,255 即是二補數的 -1 ,因此變成向下捲動
測試效果
查找到一大堆資料,還是要將需要修改既資料寫入到 巨集鍵盤 才能達至目的
要將資料寫入,可以最簡單就是將資料經 標準輸出(Standard Out) 導向至 巨集鍵盤
不過,在下建議不要使用 echo 執行 標準輸出,而是 printf
因為 echo 會在將 標準輸出 自動添加 EOL ,而且預設不會執行跳脫字元的效果
需要以 echo -en 才能達到效果,但直接使用 printf 即可,例如
printf "\x03\xFD\x01\x01\x01\x00\x00\x00\x00\x00\x01\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" | sudo tee "/dev/hidraw?"
而且 printf 可以使用格式化文字,方便製作 範本 來修改 巨集鍵盤
device="/dev/hidraw?"
template="\x03\xFD%s\x01\x01\x00\x00\x00\x00\x00\x01%s%s\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
button="\x01"
modifier="\x00"
keystroke="\x04"
printf "${template}" "${button}" "${modifier}" "${keystroke}" | sudo tee "${device}"
不過,由於 /dev/hidraw? 的擁有者及群組都屬於 root , 因此一般帳戶無法直接使用 > (大於號) 將 標準輸出 導向至 /dev/hidraw?
需要 root 或使用 | sudo tee 將 標準輸出 導向至 /dev/hidraw?
測試效果
讀取操作
使用前可以向 巨集鍵盤 查詢,並回應按鈕資訊
在 Terminal 輸入:
sudo cat "/dev/hidraw?" | xxd -g 1 -c 65 | sed -r 's/.*(([0-9A-Fa-f]{2} ){65}).*/\1/g'
等待 巨集鍵盤 回應按鈕資訊
使用另一個 Terminal 輸入:
printf "\x03\xfa\x0f\x03\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" | sudo tee "/dev/hidraw?"
最關鍵的是 第4位元組 , 用來指定 巨集鍵盤 的 選擇層 的資訊
提交查詢後,巨集鍵盤回應資料
(不知為何提交1次查詢,巨集鍵無法回應所有資料,需要每層資料都要提交2次,才能回應每層所有資料)
總結
最初接觸這種巨集鍵盤時,覺得與在下早前使用 Arduino 自製的鍵盤 或 RP2040 改裝的遊戲控制器非常相似
但分別在於在下需要每次修改內容,都需要修改原始碼、編譯、燒錄到微控制器
而巨集鍵盤則不需要編程知識便可以修改,但需要特定軟件才能修改
因此在下經常抱怨這些裝置只能使用只支援 Windows 的特定軟件
但由於在下已經使用 Arduino 之類微控制器開發板,而且在下過去亦曾經逆向工程一些裝置
因此在下才估計這類軟件是向裝置發送序列資料來修改內容
VirtualBox 亦支援 USB裝置 在 虛擬機 上運作,所以才想到在 虛擬機 運行 Windows 並執行該軟件
再讓 Wireshark 監察 USB資料 ,結果資料能正確地擷取
可能閣下會覺得能夠在 虛擬機Windows 設定內容,不需要大費周章地逆向工程
但如果考慮並非所有電腦都有足夠效能執行 虛擬機,能夠不依賴 Windows 便能夠修改內容是有必要性
而且這個逆向工程亦啟發了在下之前的鍵盤及遊戲控制器專案,可以使用序列資料修改內容
便不需要每次修改都要修改原始碼、編譯、燒錄到微控制器
最後在下將 資料寫入 自動化,但拔插 巨集鍵盤 及 檢查偵錯 仍然需要人手操作
不過在下將 操作時間最長、最容易出錯 的部分 自動化,而且不需要具備特定知識及技術的人都能完成,已經簡化了大部分工序
雖然原本就是拜託下屬執行的工作,但如果任務內容出錯,在下都要負責
所以在下覺得編寫一個能夠降低錯誤率的工具,比使用傳統工具更安全
而且降低了下屬工作的沉悶程度,應該算是一個好上司吧?
最後,在下將 資料寫入 自動化,但 拔插巨集鍵盤 及 檢查偵錯 仍然需要人手操作
不過,在下已經將 操作時間最長、最容易出錯 的部分 自動化
這樣即使是不具備特定知識及技術的人也能輕鬆完成,而且簡化了大部分工序
雖然原本就是拜託下屬執行的工作,但如果任務內容出錯,在下仍然需要負責
因此,在下認為編寫一個能降低錯誤率的工具,比使用傳統工具更安全
此外,也降低了下屬工作的沉悶程度,在下應該算是一個好上司吧?


































沒有留言 :
張貼留言