본문 바로가기

취약점 분석/안티 리버싱

IsDebuggerPresent, 우회 방법

반응형

안티리버싱 IsDebuggerPresent


[IsDebuggerPresent]

IsDebuggerPresent 내부를 들여다 보자꾸나.

mov eax, dword ptr fs:[18h]        //TEB.self를 eax에 (TEB주소 그대로 eax로)

mov eax, dword ptr [eax+30h]    //TEB.PEB를 eax에 (PEB 주소를 eax에)

movzx eax, byte ptr [eax+2]        //PEB.BeingDebugged (디버깅 중이라면 1, 아니라면 0)

ret                                                


요약 : PEB.BeingDebugged 값을 eax에 담고 리턴.


[TEB]

fs:[18h] == 현재 스레드 TEB 주소.

[eax+30h] == TEB에서 PEB주소 획득.


[PEB]

[eax+2] == PEB의 BeingDebugged 값.


FS레지스터를 통해 PEB주소를 얻고, PEB에서 BeingDebugged byte값을 eax로 받아서 리턴.

eax가 1이라면 디버깅 중이로군!

eax가 0이라면 통과.


4줄밖에 안되는 매우 간단한 안티리버싱 API 함수이므로, IsDebuggerPresent 함수를 찾아서 우회하는 것을 한번 꼬아서 인라인 함수로 직접 어셈블리로 함수를 구현하고 호출하기도 한다.


[우회 방법]

1) IsDebuggerPresent API 함수에 break걸고 호출 결과 eax를 0으로 변경.

: 매번 해줘야 해서 귀찮음

2) IsDebuggerPresent API 함수 자체를 mov eax, 0 으로 변경

: IsDebuggerPresent API 함수를 호출한다면 나쁘지 않음  (오예 좋아)

3) PEB.BeingDebugged 값 자체를 0으로 변경

: 함수를 직접 어셈블리로 구현한 인라인 함수도 우회 가능. (오예 좋아)

: !teb로 TEB 주소 조회하고, teb[30h]에서 PEB주소 획득 후, PEB.BeingDebugged 값을 0으로 바꾸면 됨.


반응형