最近公司有一個專案,其中一部分的內容需要將一款巨集鍵盤操作修改成特定內容
由於這些巨集鍵盤必須使用特定軟體才能修改內容,而且這個軟體只能透過滑鼠點擊來操作
如果只是十多個要修改還可以手動修改,但如果是數千個要手動修改會非常耗時
而且出錯率會很高,檢查時也非常困難
因此,我們需要想辦法將操作自動化,或至少能夠半自動化
鍵盤外觀
一款藍牙巨集鍵盤,共有 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 便能夠修改內容是有必要性
而且這個逆向工程亦啟發了在下之前的鍵盤及遊戲控制器專案,可以使用序列資料修改內容
便不需要每次修改都要修改原始碼、編譯、燒錄到微控制器
最後在下將 資料寫入 自動化,但拔插 巨集鍵盤 及 檢查偵錯 仍然需要人手操作
不過在下將 操作時間最長、最容易出錯 的部分 自動化,而且不需要具備特定知識及技術的人都能完成,已經簡化了大部分工序
雖然原本就是拜託下屬執行的工作,但如果任務內容出錯,在下都要負責
所以在下覺得編寫一個能夠降低錯誤率的工具,比使用傳統工具更安全
而且降低了下屬工作的沉悶程度,應該算是一個好上司吧?
最後,在下將 資料寫入 自動化,但 拔插巨集鍵盤 及 檢查偵錯 仍然需要人手操作
不過,在下已經將 操作時間最長、最容易出錯 的部分 自動化
這樣即使是不具備特定知識及技術的人也能輕鬆完成,而且簡化了大部分工序
雖然原本就是拜託下屬執行的工作,但如果任務內容出錯,在下仍然需要負責
因此,在下認為編寫一個能降低錯誤率的工具,比使用傳統工具更安全
此外,也降低了下屬工作的沉悶程度,在下應該算是一個好上司吧?
沒有留言 :
張貼留言