본문 바로가기

My Study/Reversing

RDTSC를 사용한 안티리버싱 기술

이번 안티리버싱 기법은 간단히 시간을 사용하는 방법입니다.
보통 디버깅을 하다보면 트레이스를 하게됩니다. 그렇게 프로그램 분석을 하면서
프로그램을 실행시키게 되면 정상실행 한 것보다 훨씬 많은 시간이 걸릴 것입니다.

이렇게 시간 차이를 감지하고 특정 시간보다 많은 시간이 걸려서 프로그램이 실행되게 되면
디버깅이 있다고 감지를 하는 것입니다.

이때 사용할 명령어는 RDTSC라는 어셈블리 명령어 입니다.
RDTSC ( Read Time Stamp Counter ) :  time stamp counter를 읽어내는 명령어
time stamp counter은 사이클을 측정하는 것입니다. ( 시간을 측정하는 것이 아닙니다. )
즉, 컴퓨터가 켜진 이후부터 사이클을 측정하는 것입니다. 컴퓨터가 다시 켜질 땐 사이클이 0으로 초기화가 되겠지요.
그리고 반환되는 값은 64bit로 EDX : EAX 에 저장이 되게됩니다.
자세한 내용은 인터넷을 찾아보면 많이 나오므로 생략하겠습니다.

해당 명령어를 사용한 코드를 보시겠습니다.
제가 생각한대로 RDTSC를 사용하려면 코드가 길어질꺼 같아서 간단히 main함수만 보겠습니다.


위 프로그램에 대한 설정입니다. 쭉 읽어주시면 됩니다. ^^

Func1 = 유료 사용자인지 아닌지 분석을 하는 함수
Func2 = 프로그램 실행을 하는 함수

위 프로그램은 상용 유료 프로그램입니다.
해당 프로그램을 정상적으로 이용하기 위해서는 결제를 해야합니다.
하지만 크래커는 뚫기로 했습니다.
먼저 크래커는 유료사용자인지 아닌지를 판별하는 함수를 분석하기 위해 Func1을 분석하기 시작합니다.
분석을 마치고 나온 크래커는 Func2로 들어가서 프로그램을 실행을 시켜봅니다.
하지만 프로그램이 정상적동을 하지 않습니다. 런타임 오류가 발생해버립니다.

위 프로그램을 보면 Func1을 분석을 하게 되면 프로그램 실행하는데 걸리는 시간이 정상시간보다 더욱 오래 걸리기 때문에
state값이 1로 설정되게 됩니다. 그러면 Func2는 내부에서 state값을 가지고 2인경우 프로그램이 정상 실행되고
1인경우 런타임 오류를 내버리면 됩니다.

제 나름대로 최대한 크래커 혹은 리버서가 안티리버싱 기술을 감지 못하도록 해본 것입니다.
위 코드 같은 경우는 코드가 짧아 쉽게 눈치 챌 수도 있겠지만 진짜 상용프로그램들 처럼 방대한양의 코드 속에 
저런 루틴을 숨겨 놓는다면 찾기가 힘들 것입니다. ( 진정 고수에겐 보일태지요?? )

위 코드에서 몇초 이상 분석하면 걸리냐..라고 궁금하신 분들도 계실꺼같아서
RDTSC를 1초마다 한번씩 수행하면서 EDX에 있는 값을 체크해본 결과입니다.

제 컴 같은 경우는 3~5초마다 한번씩 바뀌더군요.
아무리 분석이 빨라도 3~5초만에 분석을 한다는 것은 말이 안되겠죠??