bamboo’s blog

Bambooの気まぐれブログ

3DSにおけるプロセス間通信

今回はプロセス間通信(IPC)を用いて、ホームボタンを押す処理をGatewayコードで実装してみる。

仕組み

IPCのリクエストが行われると、リクエスト内容がスレッドローカルストレージという場所の0x80番地に書き込まれる。これがSendSyncRequestと呼ばれるsvc命令によってサーバーに送信される。サーバーがリクエスト内容を受け取ることによってはじめてリクエストが成立する。

以上を踏まえて、今回行う手順は次の通りである。

  1. スレッドローカルストレージの0x80番地に「ホームボタンを押す」という処理にあたるIPCコマンドを書き込む。
  2. svcSendSyncRequestでリクエストをサーバーへ送信する。

完成したコード

[Force Home Button]
F0F00000 00000024 // 0x24byte
EE1D2F70 E1CF01D0
E1C208F0 E59F0004
EF000032 E12FFF1E
00020003 000C0080
00000204 00000000

解説

処理内容としては以下の通り。

EE1D2F70    mrc 15, 0, r2, cr13, cr0, 3
E1CF01D0    ldrd r0, [pc, #0x10]
E1C208F0    strd r0, [r2, #0x80]
E59F0004    ldr r0, [pc, #4]
EF000032    svc #0x32
E12FFF1E    bx lr
00020003    .word 0x20003
000C0080    .word 0xC0080
00000204    .word 0x204
mrc 15, 0, r2, cr13, cr0, 3

スレッドローカルストレージへのポインタをr2に読み込む。ここにIPCコマンドを格納することになる。

ldrd r0, [pc, #0x10]

r0に0xC0080を、r1に0x204を読み込む。ホームボタンを押した際の処理は、PublishToSubscriberによって通知IDが送信されることで成立する。ここで、0xC0080はPublishToSubscriberのコマンドヘッダ、0x204はホームボタンを押した際の通知IDにあたる。

strd r0, [r2, #0x80]

r0・r1の値をr2+0x80の位置に格納する。r2+0x80は、スレッドローカルストレージ内のIPCコマンドを格納する場所にあたる。

ldr r0, [pc, #4]

0x20003をr0に読み込む。svc命令を使用する際には、予め指定されたレジスタに引数となる値を格納しておく必要がある。SendSyncRequestを使用する場合は0x20003をr0に代入しておく。

svc #0x32

3DSでは、svc命令の0x32番がSendSyncRequestにあたる。これによりスレッドローカルストレージに格納したIPCコマンドが送信される。

bx lr

サブルーチンの終了。lrに格納されているアドレスへと分岐する。

参考文献: 3dbrew