入力メソッドからタッチバーを使う方法を調べるために使った各種ツールの使い方をメモしておく。
class-dump
実行ファイルからObjective-Cのヘッダファイルを生成する。 homebrewでインストールできた。
$ class-dump /System/Library/Frameworks/InputMethodKit.framework/InputMethodKit // // Generated by class-dump 3.5 (64 bit). // // class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2015 by Steve Nygard. // ..... @interface IMKServer : NSObject <IMKServerProxy> { IMKServerPrivate *_private; } + (id)inputDelegateClassNameFor:(id)arg1; + (id)inputControllerClassNameFor:(id)arg1; + (id)connectionNameFor:(id)arg1; + (id)_clientWrapperForXPCConn:(id)arg1; + (id)_clientWrapperForDOProxy:(id)arg1; + (id)imkServerSingleton; - (id)keyBindingManager; ...
lldb
class-dumpでは、だいたいの箇所がid型になってて詳細な使い型がわからない。 そのライブラリを使っていそうなプロセスにlldbでattachして使い方を調べた。
まずはSIPが有効だとプロセスにattachできないので、Mac OS X El CapiptanでSIPを無効化する - Qiitaなどを参考に無効化する。
目的のプロセスを調べて、attachする。 入力メソッドにattachする場合はそのマシンの入力が死ぬので、別マシンからsshするといい。
$ ps ax | grep '[E]mojiFunctionRowIM' 402 ?? Ss 0:03.51 /System/Library/Input Methods/EmojiFunctionRowIM.app/Contents/PlugIns/EmojiFunctionRowIM_Extension.appex/Contents/MacOS/EmojiFunctionRowIM_Extension $ lldb (lldb) attach 402
あとは各種コマンドを使って挙動を調べていく。 だいたい以下のコマンドを使った。
ブレイクポイントの設定
特定のセレクタにブレイクポイントを設定する。
br set --selector inputDelegateClassNameFor:
特定のクラスの全メソッドにブレイクポイントを設定する。
br set -r '\[ClassName .*\]$'
表示
# オブジェクトの表示 po $obj # 値の表示 p (BOOL)[$obj isHoge]
メソッド呼び出し時に使われるレジスタ
- self: $rdi
- _cmd $rsi
引数
変数への代入
expr id $foo = [$obj foo]
otool
それでも分からないやつは逆アセンブルした。 どのメソッド呼んでいるかなどを主に見た。
$ otool -tV /System/Library/Frameworks/InputMethodKit.framework/InputMethodKit /System/Library/Frameworks/InputMethodKit.framework/InputMethodKit: (__TEXT,__text) section -[IMKUICandidateController init]: 0000000000001d0c pushq %rbp 0000000000001d0d movq %rsp, %rbp 0000000000001d10 pushq %r15 0000000000001d12 pushq %r14 0000000000001d14 pushq %r12 0000000000001d16 pushq %rbx 0000000000001d17 subq $0x10, %rsp 0000000000001d1b leaq -0x30(%rbp), %rax 0000000000001d1f movq %rdi, (%rax) 0000000000001d22 movq 0xd6fc7(%rip), %rcx ## Objc class ref: IMKUICandidateController 0000000000001d29 movq %rcx, 0x8(%rax) 0000000000001d2d movq 0xd2dc4(%rip), %r14 ## Objc selector ref: init 0000000000001d34 movq %rax, %rdi 0000000000001d37 movq %r14, %rsi 0000000000001d3a callq 0x89b5c ## Objc message: -[[%rdi super] init] 0000000000001d3f movq %rax, %rbx 0000000000001d42 testq %rbx, %rbx 0000000000001d45 je 0x1de9 ....