みずぴー日記

人間の再起動ボタンはハワイのビーチにある

🔬Appleの非公開APIの調べ方

入力メソッドからタッチバーを使う方法を調べるために使った各種ツールの使い方をメモしておく。

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

引数

  1. $rdx
  2. $rcx
  3. $r8
  4. $r9
  5. スタックにつまれる。 po ((id)$rsp+1)

変数への代入

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
....