이 프로그램은 몇 밀리세컨드 후에 종료되는가
정답 인증은 MD5 해쉬값(대문자) 변환 후 인증하시오.
해당 메시지박스 출력, 일정 시간 후에 종료.
Entrypoint에서 pushad 발견
PEiD로 확인. upx로 패킹되어 있는 것을 발견
upx로 압축 해제
몇 밀리세컨드 후에 종료된다는 문제의 힌트를 듣고, killprocess나 terminateprocess 등의 함수를 찾아보았다.
KillTimer 함수를 보고, 몇 밀리세컨드 후에 종료된다는 힌트에서 타이머가 필요할 것 같아 Timer를 검색하였다.
SetTimer의 인자로 밀리세컨드가 들어가 있을 것이라고 추측.
SetTimer 함수 MSDN에서 검색.
그냥 실행 시에 특정 문구를 출력하는 에러 발생
에러 내용
해당 에러 내용을 문자열 검색
발견
역추적. IsDebuggerPresent 함수 발견!
IsDebuggerPresent 함수
디버거 탐지 시 0이 아닌 값, 디버거 미탐지 시 0을 반환함.
IsDebuggerPresent 함수 통과한 이후 반환되는 값(EAX)를 0으로 직접 수정한 후, 이어서 실행하면 해당 함수를 우회할 수 있다.
인자값
3번째 인자가 밀리세컨드 단위임을 감안했을 때, 0x2EE(750) 밀리세컨드는 1초도 되지 않는 시간이기 때문에, 문제 해결과 직접적으로 관련이 없는 부분이었음을 알 수 있다.
4번째 인자가 0(NULL)일 경우에는 자동으로 WM_TIMER가 실행되는데, WM_TIMER는 SetTimer에서 콜백함수를 주지 않은 경우에, 기본적으로 설정되어있는 함수로, 메시지를 출력한다.
SetTimer는 직접적으로 문제 해결과 관련이 없는 것 같아, 다시 문제를 살펴보고 함수 전체 목록을 뒤져보니 Kernel32.Sleep이라는 함수가 눈에 띄었다.
timeGetTime 함수는 윈도우가 시작된 후부터 지금까지 흐른 시간을 밀리세컨드로 반환하는 함수인데, 이 함수가 'call edi'를 통해 두 번 실행되면서 두 개의 시간 값을 가져오고,
두 값의 차를 특정 값(0x337B)과 비교하는 분기문이 존재했다.
특정 값보다 두 시간 값의 차가 작은 경우에는 계속해서 sleep 명령을 통해 특정 값을 넘을 때까지 시간을 다시 측정한다.
결국 이 프로그램은 0x337B(13179) 밀리세컨드 후에 종료되는 프로그램이다.
정답
DB59260CCE0B871C7B2BB780EEE305DB