我是如何Hack一個機器人的?

jopen 8年前發布 | 12K 次閱讀 安卓開發

在Hack Day這樣的偉大節日里,還是應該做一點Hack的事。很久沒有干過這么刺激的事,想想也覺得有點小激動。

Blabla,當然這個Robot可能沒有你想的那么高端,Hack的目的只是為了控制這個機器人。而這個所謂的機器的主要功能都集中在客戶端上,我們可以在手機上通過BLE(藍牙低功耗)來控制這個機器人。

所以,我們的目的其實很簡單——自己寫APP來控制這個機器人。而APP的主要功能都是通過藍牙控制來實現的,而藍牙協議的第一步就是連接。在最開始的時候我想的連接方式是PIN碼 + AT指令,結果發現我完全錯了,BLE實際上更簡單。

因此,我覺得有PIN碼的存在,所以第一步就是抓包。

藍牙通訊抓包一

為了做到這一步,我們需要一個大名鼎鼎的“WireShark”。不過,我們是要拿這個軟件來分析日志。

第一步,我們需要在開發者選項中啟用日志分析。在開發者選項中有一個功能, [Enable Bluetooth HCI snoop log/啟用藍牙 HCI 信息收集日志]。如下圖所示:

第二步,我們我們就可以打開應用,做一些正常的操作,然后這些操作就會存儲到一個日志文件里。而這個日志文件只能用WireShark打開。

第三步,就是用WireShark打開這個日志。從日志中找尋手機發往機器人的指令,發現里面都看不懂。

接著想起來,似乎可以反編譯他們的代碼。

反編譯代碼

開始嘗試反編譯代碼,發現步驟也挺簡單的:

  1. 用apktool反編譯apk
  2. 用dex2jar將dex轉為jar
  3. 用jd-gui查看反編譯后的軟件,并導出
  4. 查看代碼

雖說原理很簡單,但是實踐起來就坑了。先反編譯了最新的APK,然后發現這個APK被360加固了。。接著開始回溯這個軟件的版本,360加固出得比這個軟件晚,那么我應該可以找到這個軟件的早期版本。

而事實是,我在國內都找不到這個APK的早期版本,只好拿包名去搜索,然后中獎了——找到了一個早期的版本,并且反編譯成功了。

接著,我全局搜索PIN碼等等的東西都沒有結果,我的思路錯了。。。

最后,我看到了代碼里的:

Log.i("robotControl", "forward left 30");

既然,他可以打日志,那我應該是可以查看日志的。

日志記錄

于是,我找到了Android的logcat命令,然后湊了一條指令出來。

adb -d logcat  com.example:D *:D > debug.log

運行軟件,分析日志。從大量的數據里找到:

D/BluetoothAdapterService(23908452)(16911): getState() - mAdapterProperties: com.android.bluetooth.btservice.AdapterProperties@1e554c00
D/BluetoothAdapter(17239): 448307125: getState(). Returning 12
D/BtGatt.GattService(16911): registerClient() - UUID=037decf9-4d7e-49d8-9f82-85202eea480f

看著日志,看著日志。突然有一個瞬間,我意識到BLE是不需要PIN碼的。我只需要找到對應的UUID,以及對應的Service就可以了。

現在,我可以寫自己的應用了。

編寫自己的APP

這一次,在網上簡單地找了一個Cordova BLE的示例。(后面才發現這個坑挖得太深,以至于掉了進去。Cordova對WebSocket的支持不好,不過這和這個主題沒有啥關系。。)

分析設備

按代碼的邏輯,我們可以在連接上設備的時候查看設備的服務——并根據具體的服務及txCharacteristic,來做對應的發送數據。而依據write數據的代碼,我們需要兩個東西一個是設備的UUID,一個Characteristic。一個藍牙4.0的終端可以包含多個Service,一個Service可以包含多個Characteristic。

如,我們要發送和接收數據都需要有對應的Characteristic。藍牙技術聯盟似乎定義了一些GATT(Generic Attribute Profile ),如下是一個設備的縮略數據:

{
    "name": "Battery Demo",
    "services": [
        "1800"
    ],
    "characteristics": [
        {
            "service": "1800",
            "characteristic": "2a00",
            "properties": [
                "Read"
            ]
        }
    ]
}

如這個設備,提供了一個代碼為1800的服務。這個服務里包含了一個characteristic為2a00的屬性,我們只需要通過1800這個Service UUID,以及characteristic 2a00就可以讀取這個設備的Device Name——這個是藍牙技術聯盟定義的Characteristics。

而這時,就找到了UUID為fff0,TX Characteristic為fff1。

控制機器人

所以我們的設備信息便如下所示:

var robotInfo = {
    serviceUUID: "0000fff0-0000-1000-8000-00805f9b34fb",
    txCharacteristic: "0000fff2-0000-1000-8000-00805f9b34fb", // transmit is from the phone's perspective
    rxCharacteristic: "0000fff1-0000-1000-8000-00805f9b34fb"  // receive is from the phone's perspective
};

接著,繼續看之前的反編譯代碼,發現他是這么控制的。

  1. 左轉指令X2
  2. 右轉指令X3
  3. 前進指令X1
  4. 后退指令X4

當然,他還有更多的指令,只是我不需要那么多。。。然后我找到了一個名為nipplejs的庫,來當游戲手柄。

小結

現在,我們已經可以控制這個機器人了。

來自: http://www.phodal.com/blog/how-to-hack-a-robot/

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!