😾

gdbによるプログラムの動的解析を防ぐ手法の紹介とその手法の回避方法

2023/02/06に公開約2,400字

想定環境

x64GNU/Linux

この記事ではgdbなどのデバッガによる動的解析を防ぐためのアンチデバッグ手法を解説します。
またその手法による解析拒否を回避する方法も解説します。

ptraceによるアンチデバッグ手法

ptraceはシステムコールです。
gdbなどのデバッガはptraceを用いて他のプログラムにアタッチ(接続)しています。

ここで紹介するアンチデバッグ手法は、デバッガが使われていると判断したら、すぐにプログラムを終了する手法です。

具体的なデバッガ検知のコードを見てみます。

anti_debug.c
#include <stdio.h>
#include <sys/ptrace.h>

int main(void) {
    if (ptrace(PTRACE_TRACEME, 0, 1, 0) == -1) {
        printf("デバッガ使うな!!!!\n");
	return 1;
    } else {
        printf("デバッガを使用していないことを確認したので通常の処理を続行します\n");
	return 0;
    }
}

このプログラムはptraceで自分自身にアタッチし、ptraceが失敗するかを確認します。
失敗すれば、デバッガが使われていると判断できるのでぶちギレメッセージとともにプログラムを終了しています。

デバッガを使わず普通に実行してみましょう。

gcc anti_debug.c
./a.out

"デバッガを使用していないことを確認したので通常の処理を続行します"と出力されましたね。
ではgdbで実行してみましょう。

gdb a.out
break main
run
next

"デバッガ使うな!!!!"とキレらました、、、

アンチでバッグ手法の回避方法

ではどうしてもこのアンチでバッグ手法を回避したい場合どうすればよいのでしょうか。
回避方法としては、パッチを当てることです。
バイナリの一部を変更することをパッチを当てると表現します。
例えば16進数エディタであるhexeditなどを用いて、デバッガを検知している部分の機械語をnop命令で塗りつぶします。

では実際にやってみましょう。
まずobjdumpを用いて逆アセンブルします。

objdump -M x86-64 -M intel -d a.out
objdumpの出力の一部
0000000000001145 <main>:
    1145:	55                   	push   rbp
    1146:	48 89 e5             	mov    rbp,rsp
    1149:	b9 00 00 00 00       	mov    ecx,0x0
    114e:	ba 01 00 00 00       	mov    edx,0x1
    1153:	be 00 00 00 00       	mov    esi,0x0
    1158:	bf 00 00 00 00       	mov    edi,0x0
    115d:	b8 00 00 00 00       	mov    eax,0x0
    1162:	e8 d9 fe ff ff       	call   1040 <ptrace@plt>
    1167:	48 83 f8 ff          	cmp    rax,0xffffffffffffffff
    116b:	75 13                	jne    1180 <main+0x3b>
    116d:	48 8d 3d 94 0e 00 00 	lea    rdi,[rip+0xe94]        # 2008 <_IO_stdin_used+0x8>
    1174:	e8 b7 fe ff ff       	call   1030 <puts@plt>
    1179:	b8 01 00 00 00       	mov    eax,0x1
    117e:	eb 11                	jmp    1191 <main+0x4c>
    1180:	48 8d 3d a9 0e 00 00 	lea    rdi,[rip+0xea9]        # 2030 <_IO_stdin_used+0x30>
    1187:	e8 a4 fe ff ff       	call   1030 <puts@plt>
    118c:	b8 00 00 00 00       	mov    eax,0x0
    1191:	5d                   	pop    rbp
    1192:	c3                   	ret    
    1193:	66 2e 0f 1f 84 00 00 	nop    WORD PTR cs:[rax+rax*1+0x0]
    119a:	00 00 00 
    119d:	0f 1f 00             	nop    DWORD PTR [rax]

e8 d9 fe ff ffというところを90 90 90 90 90 にしてみましょう。
そしてgdbで実行すると
"デバッガを使用していないことを確認したので通常の処理を続行します"と表示され回避することができました。

Discussion

ログインするとコメントできます