toshiki

電動キックボードを解析してファームウェアをRustで書き直した話

· Hacker News / bensimms.moe #130

市販のe-スクーターをSWDでダンプ→Ghidraで解読→CANバスを盗聴→Embassy(no_std)でファームを丸ごとRustに置き換えた一部始終。

  • #rust
  • #embedded
  • #reverse-engineering
  • #hardware
  • #can-bus

#なぜ今日これを選んだか

「Rust+ハードウェア」の目標を掲げてから、教科書的な入門と実物のあいだに大きな溝があると感じていた。この記事は市販の電動キックボード(Egret GT)という実物を相手に、基板を開けるところからRustで動かすところまで一気通貫で見せてくれる。自分が最終的にやりたい「センサーをRustで読む」の完成形が、ここに全部ある。

#要点

  • 入口はSWDポート4ピン。MCUはAT32F415(STM32F103の互換品)で、OpenOCDでフラッシュとRAMをダンプし、Ghidraで ARM Cortex のアセンブリとして読み解いた
  • USB-Cの中にCANバスが通っていた。ESP32-C6+CANトランシーバ(SN65HVD230 / MCP2515)で自作ロガーを組み、egui製の可視化ツールで「メッセージIDをY軸・時間をX軸」に散布して意味を当てた。Bluetooth側のCH573とは57600bps前後のUARTで会話している
  • 書き直しはEmbassy(非同期ランタイム)+no_std。ADC読み取り・状態管理・操作の状態機械・UI描画をタスクに分け、ディスプレイは mipidsi、CAN/BTのビット単位パースは deku のマクロで定義。AT32F415向けHALが無かったので STM32F1 向けのEmbassyコードを土台に、レジスタ名をGhidraのHAL関数と突き合わせて移植した

#自分にとっての示唆

いま自分が持っている「はんだごてしながら開発したい」「SQLもやりたい」「ハードウェアまで手を出すとやばいかな」という散らばりに、この記事は順番を教えてくれる。筆者がやったことは大きく3段しかない。①既存の中身を読む(ダンプ→逆アセンブル)②通信を観察する(ロガーで貯めて可視化)③読めたものをRustで書き直す。最初の2段は「作る」ではなく「見る」で、見えたぶんだけ書く量が決まる。

だから自分の月水金Rust30分でやるべきことも決まる。いきなりファームウェアを書かない。まず手元のマイコン(STM32F1系ならこの記事の土台がそのまま使える)でEmbassyの blinky を動かし、次にUARTかCANで流れているバイト列を1回ダンプして眺める。30分×何回かで「見る」が終わったら、初めて deku でパーサを1つ書く。手元カメラが届いたら、はんだ付けと画面を同時に記録して、詰まった箇所をAIに見せながら解く。センサー読み取りのゴール(#130)はこの3段の縮小版でしかない、と分かったのが今日の収穫。