1つは、Androidのアンチデバッグです。
アンチデバッグは、コード保護において非常に重要な役割を果たします。攻撃者を完全に阻止することはできませんが、攻撃者の分析時間のコストを増加させる可能性があります。現在、ほとんどのAndroidアプリは強化されています。アプリのデバッグと分析を防ぐために、強化機能にさまざまなデバッグ防止機能が追加されています。たとえば、自分でptraceする、関数の実行時間を確認する、/ proc / $を読み取るなどです。 pid / wchanまたは/ proc / $ pid / task / $ pid / wchanファイル情報を使用してデバッグステータスを判断し、/ proc / $ pid / statまたは/ proc / $ pid / task / $ pid / statファイル情報を読み取ってデバッグステータスを判断します。デバッグステータス、読み取り/ proc / $ pid / statusまたは/ proc / $ pid / task / $ pid / statusファイルは、TracerPidの検出、デバッグプロセス名の読み取りと検出、デバッグポートの検出などを行います。インターネット上にはAndroidのアンチデバッグに関する記事がたくさんあります。Androidのアンチデバッグの検出方法について詳しく知りたい場合は、[https://bbs.pediy.com/thread-223324にまとめられている方法をご覧ください。 htm]。この記事では、/ proc / $ pid / statusファイルと/ proc / $ pid / wchanファイルを読み取って、アプリがデバッグされているかどうかを確認する方法についてのみ説明します。
2. / proc / $ pidを読み取る検出原理の分析
1. / proc / $ pidの下のステータスファイルを読み取り、デバッグされていることを検出します
Androidのデバッグ状態では、Linuxカーネルはプロセスステータス情報を/ proc / $ pid / statusまたは/ proc / $ pid / task / $ pid / statusに書き込みます。TracerPidフィールドは、プロセスをデバッグするプロセスのPidに書き込まれます。その中で、プロセスの現在の状態が[状態]フィールドに書き込まれ、値は次のいずれかになります。
R (running)", "S (sleeping)", "D (disk sleep)", "T (stopped)", "t(tracing stop)", "Z (zombie)", "X (dead)"
Stateがt(トレース停止)またはT(停止)の場合、デバッグおよびトレースされていることを意味します。したがって、アンチデバッグの方法の1つは、継続的なポーリングを通じて/ proc / $ pid / statusまたは/ proc / $ pid / task / $ pid / statusファイルを読み取ることにより、TracerPidまたはStateの値を確認することです。TracerPidがそうでない場合0は、プロセスがデバッグされていることを意味します。状態値がt(トレース停止)またはT(停止)の場合、デバッグおよび追跡されます。以下に示すように:
2. / proc / $ pid / stat、/ proc / $ pid / task / $ pid / statを読み取り、デバッグされていることを検出します
プロセスがデバッグされているとき、カーネルは/ proc / $ pid / statファイルと/ proc / $ pid / task / $ pid / statファイルの3番目のフィールドにtフラグを書き込みます。
3.读取/ proc / $ pid / wchan、/ proc / $ pid / task / $ pid / wchan
wchanファイルの内容は、プロセスがスリープしているときにカーネルが現在実行している関数を示しています。プロセスがデバッグされると、カーネルはptrace_stop情報を/ proc / $ pid / wchanファイルと/ proc / $ pid / task / $ pid / wchanファイルに書き込みます。
3、カーネルを変更します
次の図に示すように、 カーネルソースコードと「2」の関連情報コードは、カーネル/ fs / procディレクトリにあります。
1.状態識別値を変更します
ロゴの書き込みに関連する情報は、以下に示すように、カーネルファイル/fs/proc/array.cにあります。
元のコードの内容:
static const char * const task_state_array [] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
上記の内容の「t(トレース停止)」と「T(停止)」を「S(スリープ)」に置き換える必要があります。アプリのデバッグ方法に関係なく、カーネルは通常の状態で書き込みを行い、アンチに対抗します。デバッグ検出。変更されたコードは次のとおりです。
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
///ADD START
//"T (stopped)", /* 4 */
"S (sleeping)", /* 4 */
///ADD END
/*
///ADD START
//"t (tracing stop)",/* 8 */
*/
"S (sleeping)", /* 8 */
/*
///ADD END
*/
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
2.TracerPid関連を変更します
タグの書き込みに関連する情報は、以下に示すように、カーネルファイル/fs/proc/array.cのtask_state関数にあります。
その中で、tpidは現在デバッグ中のプロセスのPidを表し、常にtpidを0に変更します。TracerPidの検出をバイパスできます。次のように変更した後:
3.wchanファイルに関連する情報を変更します
ファイル/ proc / $ pid / wchan、/ proc / $ pid / task / $ pid / wchanカーネル書き込み関連のコードパスは、以下に示すように、\ fs \ proc \ base.cにあります。
#ifdef CONFIG_KALLSYMS
/*
* Provides a wchan file via kallsyms in a proper one-value-per-file format.
* Returns the resolved symbol. If that fails, simply return the address.
*/
static int proc_pid_wchan(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task)
{
unsigned long wchan;
char symname[KSYM_NAME_LEN];
wchan = get_wchan(task);
if (lookup_symbol_name(wchan, symname) < 0)
if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
return 0;
else
return seq_printf(m, "%lu", wchan);
else
return seq_printf(m, "%s", symname);
}
#endif /* CONFIG_KALLSYMS */
上記のシンボル名を記述し、フィルターシンボル名にtraceキーワードを含めるように変更してから、sys_epoll_waitを記述します。変更後は、次のようになります。
#ifdef CONFIG_KALLSYMS
/*
* Provides a wchan file via kallsyms in a proper one-value-per-file format.
* Returns the resolved symbol. If that fails, simply return the address.
*/
static int proc_pid_wchan(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task)
{
unsigned long wchan;
char symname[KSYM_NAME_LEN];
wchan = get_wchan(task);
if (lookup_symbol_name(wchan, symname) < 0)
if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
return 0;
else
return seq_printf(m, "%lu", wchan);
else{
///ADD START
if(strstr(symname,"trace")){
return seq_printf(m, "%s","sys_epoll_wait");
}
///ADD END
return seq_printf(m, "%s", symname);
}
}
#endif /* CONFIG_KALLSYMS */
4、コンパイルしてフラッシュ
変更を保存した後、Androidソースコードのルートディレクトリで次のコマンドを実行してフラッシュパッケージをコンパイルしてからフラッシュします。
source build/envsetup.sh
brunch oneplus3-userdebug
WeChatパブリックアカウントをフォローして、記事の更新を時間内に取得します。