본문 바로가기

Unpacking/Unpacking Tech

Stub Code 특성을 이용한 OEP 찾기

Visual Studio로 컴파일 되었다면 특유의 CRT 코드가 있다. Stub Code라고도 하는데 GetStartupInfo, GetVersion, GetCommandLine(A/W) 등의 함수를 호출한다. OEP를 찾는 일반적인 방법은 언패킹 또는 복호화 코드가 끝나고 원래의 코드로 점프하는 지점을 찾는 것이다.


하지만 컴파일러마다 삽입하는 Stub Code 특성을 이용해 OEP를 찾을 수 있다. 위에서 설명한 Stub Code에서 호출하는 함수 중 하나를 선택해서 브레이크 포인트를 거는 것인데 여기서는 GetStartupInfo 함수에 걸어보겠다. 실제로 VM Protector로 패킹된 파일의 OEP를 x64dbg를 이용해 찾아보겠다.


GetStartupInfo 함수는 프로그램 특성에 따라 A(ANSI)/W(Wide Unicode)로 나누어지기 때문에 둘 다 브레이크 포인트를 걸었다.



GetStartupInfiA/W 둘 다 브레이크 포인트가 걸렸다. 패킹된 파일의 엔트리 포인트가 실행되기 전의 호출은 넘기고 엔트리 포인트 실행 이후 브레이크 포인트에 대해서 콜스택을 분석한다.

계속 분석하다보면 다음 콜스택을 확인할 수 있다.



1367040에 가보면 아래로 수많은 Call을 하는 것을 볼 수 있다. Stub Code에서 호출하는 함수들에 브레이크 포인트를 걸면 모두 걸린다는 것을 확인할 수 있다. 



여기서 계속 내려가다보면 다음과  같은 코드를 볼 수 있다.



실제 레지스터 값들을 확인하면 WinMain에 사용되는 인자임을 알 수 있다. 1384FF5가 실제 WinMain 함수의 주소가 된다.

하지만 패킹이 풀리더라도 API 난독화는 해제되지 않기 때문에 API 복구 작업이 필요하다. 호출되는 함수들을 F7로 따라가다보면 10번 내외의 Call을 해서 RET를 이용해서 실제 Dll에 있는 함수로 점프한다는 것을 알 수 있다. 이렇게 되면 CFG(Control Flow Graph)를 제대로 확인할 수 없기 때문에 분석이 힘들어진다.


어쨋든 Visual Studio로 컴파일 된 파일은 CRT 코드에서 호출하는 함수를 추적하여 OEP를 알아낼 수 있다. 이외의 컴파일러에서 삽입하는 Stub Code 특징을 알고있으면 언패킹 작업에 유리하다.