본문 바로가기
reversing

고급 안티 디버깅

by 코끼리_땃쥐 2022. 10. 20.
반응형
고급 안티 디버깅 기법

PE 프로텍터에서 주로 사용되는 고급 안티 디버깅 기법의 공통된 특징은 기술적인 난이도가 높을뿐만 아니라 리버서를 정신적, 육체적으로 지치게 만든다는 것입니다.

수없이 많은 가비지 코드, 조건 분기문, 루프문, 암호화/복호화 코드 그리고 도대체 그, 깊이를 파악할 수 없는 Call_tree에 빠져서 허우적대다 보면 자신이 지금 어디쯤 와 있는지 알 수 없게 되버립니다. 정작 분석하고 싶은 코드에서 접근조차 못하고 엉뚱한 곳에서 헤매게 되는 것이죠. 이런식으로 리버서를 혼란시켜놓고, 중간 중간 Dynamic 아티디버깅 기법을 살짝 섞어 놓으면 그야말로 속수무책으로 당할 수박에 없는 상황이 되어버립니다.

물론 디버깅 자체가 아예 불가능한 것은 아닙니다만, 그 난이도가 매우 높습니다. 디버깅 경험이 많은 숙련된 리버싱 전문가들도 PE프로텍터를 분석하는 굉장히 애를 먹고, 오랜시간이 소요됩니다. 더구나 완벽히 분석한다는 것은 그야말로 대단히 어려운 작업이라고 말할 수 있습니다.

 

가비지 코드

의미 없는 코드를 대량으로 추가시켜서 디버깅을 힘들게 만드는 기법입니다. 가비지 코드 중간중간에 진짜 의미 있는 코드를 섞어 버리거나 다른 안티 디버깅 기법을 혼합해서 사용하면 디버깅이 매우 힘들어집니다. 

 

Breaking Code Alignment

IA-32 Instruction을 잘 이해한 상태에서 정교하게 어셈블리 프로그래밍을 하면, 디버거의 디스어셈블 과정에 혼란을 줄 수 있습니다. 즉 디스어셈블리 코드가 깨진 것처럼 보이게 됩니다.

코드 사이에 (정교하게 계산된) 불필요한 코드를 삽입 시켜 디스어셈블리 코드의 가독성을 떨어뜨리는 것이 'Breaking Code Align-ment' 기법입니다.

코드가 잘 파악되지 않는 상황에서 함부러 StepOver[F8] 등의 명령으로 트레이싱 하다간 다른 안티 디버깅 기법이 쳐놓은 덫에 걸릴 수 있습니다. 리버서를 매우 성가시게 하는 기법 중 하나입니다.

 

Encryption/Decryption

Encryption/Decryption(암호화/복호화) 기법은 프로그램의 코드와 데이터를 숨기기 위해 패커/프로텍터에서 자주 사용되는 기법입니다.

 

Stolen Bytes(Remove OEP)

Stolen Bytes(또는 Remove OEP) 기법은 원본 코드의 일부(주로 OEP 코드)를 패커/프로텍터가 생성한 메모리 영역으로 옮겨 실행시키는 기법입니다.

이 기법의 장접은 프로세스 메모리를 덤프 시켰을때 OEP코드의 일부분이 제거 되었기 때문에 OEP코드의 일부분이 제거 되었기 때문에 덤프된 파일은 정상적으로 실행되지 않습니다.(Anti-Dump 기법) 또 다른 장점으로는 Stolen Bytes가 적용된 파일을 다른 패커/프로텍터로 다시 압축했을때 리버서에게 혼란을 줄 수 있습니다. 언팩을 했을 때 눈에 익숙한 OEP코드가 아닌 다른 형태의 코드가 나타나기 때문에 현재 자신이 언팩을 성공한것인지 아니면 더 진행해야 하는지 혼란스러워집니다(이런 상황을 '길을 잃고 헤맨다'라고 표현합니다).

 

API 리다이렉션

디버깅 할때 코드 흐름을 대략적으로 빨리 파악할 수 있는 좋은 방법은 주요 Win32 API(파일, 레지스트리, 프로세스, 네트워크 등)에 BP를 설치하는 것입니다.

주요 API의 시작 코드에BP를 설치하고 디버기 프로세스를 실행 합니다.

만약 BP목록에 있는 API를 호출한다면, 실행이 멈추고 스택에는 리턴 주소가 저장됩니다.

이제 리턴 주소에서부터 디버깅을 해나가면 됩니다. 디버깅해야 할 코드가 매우 큰 경우 이런방법으로 매우 효과적으로 핵심 코드에 다가갈 수 있습니다. API리다이렉션(API Redirection)이란 바로 위와 같은 디버깅 노하우를 회피하는 기법입니다. 프로텍터는 주요 API들의 코드 전체(혹은 일부)를 다른 메모리 영역으로 복사합니다.

그리고 보호 대상 프로그램의 코드를 분석해야 해당 API를 호출하는 코드를 패치시켜서 자신이 복사해둔 API코드가 실행 되도록합니다. 따라서 원본 API주소에 BP를 설치 해봐야 소용이 없습니다.

 

Debug Blocker(Self Debugging)

Debug Blocker(Self Debugging) 기법은 말 그대로 자기 자신을 디버깅 모드로 실행 시키는 고급 안티 디버깅 기법입니다.

Debug Blocker 기법의 장점은 크게 두가지 입니다.

첫 번째는 디버깅 방지입니다. 실제 원본 코드를 실행하는 자식 프로세스는 이미 디버깅 중이므로 원칙적으로는 다른 디버거를 이용해서 Attach 할 수 없습니다.

두 번째 자식(Debuggee) 프로세스를 제어(Control)할 수 있다는 것입니다. 디버거 - 디버기 관계에서 디버거는 막강한 권한을 가지고 있습니다. 즉 디버기 프로세스의 예외를 처리하고 실행 흐름을 제어하는 등의 작업을 수행할 수 있습니다. 그런데 특히 두번째 장점으로 인해서 디버깅이 매우 까다로워집니다.

일반적인 안티 디버깅 기법과 Debug Blocker 기법을 비교해보겠습니다.

 

왼쪽은 일반적인 SEH 기법을 이용한 안티 디버깅 예제이고, 오른쪽은 Debug Blocker 기법을 이용한 안티 디버깅 예제입니다.

일반적인 SEH기법의 경우 예외 처리기 코드가 같은 프로세스 메모리 공간에 위치하지만, Debug Blocker 기법의 경우 디버기 프로세스에서 발생한 예외를 처리하기 위해 예외처리기 코드 위치는 디버거 프로세스에 존재합니다(디버기에서 발생한 예외에 대한 우선 처리권은 디버거에게 있다는 것을 기억하기 바랍니다).

따라서 자식(Debuggee) 프로세스를 디버깅 하기 위해서는 기존 디버거의 연결을 끊어야하는데, 그러면서 자식 프로세스는 정상적인 실행이 불가능해집니다. 이것이 바로 Debug Blocker를 리버싱하는데 가장 어려운 부분입니다.

반응형

'reversing' 카테고리의 다른 글

PE File Format 구조  (0) 2022.11.25
바이트 오더링  (0) 2022.11.03
안티 디버깅 Dynamic  (1) 2022.10.05
안티 디버깅 Static  (2) 2022.10.04
NtQueryInformationProcess  (0) 2022.09.29

댓글