Open8

iOSの代表的なアンチデバッギング手法に関して

MM

コード中から自らのプログラムがデバッガにアタッチされていることを検出する手法がありますよ〜と。

https://developer.apple.com/library/archive/qa/qa1361/_index.html

初心者の私にはコードを見てもなかなか何しているか理解できなかったので細かく見ていくスレッド
さらに何か応用できれば

MM

鍵となるというか、メインは'sysctl'ってやつ
カーネルパラメーターを読み書きしたりするときに使う。

ほぼほぼ使い方は同じだと思うのでFreeBSDの日本語マニュアルを参照
https://nxmnpg.lemoda.net/ja/3/sysctl

MM

このフラグ(bit)が立っているかどうか調べれば、debugされているか分かるという魂胆。
0x00000800 → 100000000000

MM

p_flagの値を取得したいので、ここでsysctlを使用する。

sysctlの第一引数で取得/書き込みしたいパラメータを指定する。
型はInt32の配列である。
パラメータの指定方法は、ツリー構造になっており、配列のindexが大きくなる度に枝分かれしていくようなイメージ。

p_flagに関しては、kinfo_procプロパティのkp_procプロパティから得られる。
よって、先ほど示したmanページを参照すると
CTL_KERN→KERN_PROC→KERN_PROC_PID→(自pid)
でkinfo_procが得られることが分かる。

よって以下のように指定してる。

    mib[0] = CTL_KERN;
    mib[1] = KERN_PROC;
    mib[2] = KERN_PROC_PID;
    mib[3] = getpid();
MM

sysctlを呼び出して0以外が返ってくると何らかのエラーが発生してるのでここで終了させる
第3引数で指定したパラメータの値を受け取っている。

    junk = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0);
    assert(junk == 0);
MM

以下でp_flagが取得できる

info.kp_proc.p_flag
MM

最後にフラグチェック

(info.kp_proc.p_flag & P_TRACED) != 0

フラグが立っていれば&演算で当該bitが1&1=1になる。→ デバッグ中
立っていなければ&演算の結果は0なる。→ デバッグ中でない