코드엔진 Basic RCE L10 문제를 풀어보았다.
문제는 다음과 같다. OEP를 구한 후 '등록성공'으로 가는 분기점의 OPCODE를 구하라는 문제이다.
파일을 실행시켜보면 문자 입력이 안되는 창이 뜬다.

DIE에 올려보았다. ASPack로 압축되어있다고 뜬다.

ASPack를 언패킹할 수 있는 unipacker로 압축을 풀어주려고 했지만, 해당 모듈에서는 패커를 감지하지 못해 실패했다.
따라서 패킹을 수동으로 푸는 방법밖에 없는 것 같다. 찾아보니 Aspack를 언패킹하는 방법에는 두 개가 있다고 한다.
첫 번째는 RET C를 찾아 OEP를 찾는 방법이고, 두 번째는 하드웨어 BP를 이용해서 언패킹하는 방법이다. 하나씩 알아보자.
DIE에 패킹된 파일을 올려보았을 때, EP는 0x456001이라고 뜬다.
x64dbg에서도 처음에 F9로 패킹된 파일의 EP로 이동할 수 있고, 여기서 PUSHAD명령어를 확인할 수 있다. 이부분에서 현재 레지스터(EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI)를 스택에 저장한다.
DIE의 PE를 눌러 들어가서 IMAGE_NT_HEADERS 안의 IMAGE_OPTIONAL_HEADER에 들어가면 AddressOfEntryPoint(메모리로부터의 상대주소 RVA)가 0x56001, ImageBase가 0x400000인 것을 볼 수 있다.  프로그램이 메모리에 로딩 시 ImageBase + AddressOfEntryPoint로 저장되므로, 진입점은 0x00056001 + 0x00400000 = 0x00456001(VA, 가상메모리의 절대주소)이다.
스크롤을 내리다보면 POPAD와 그 밑의 RET C를 확인할 수 있다. 
메모리 및 레지스터를 POPAD로 복구 후 OEP로 분기하기 위해 RET C 명령어를 수행한다.
pop rip와 같아 push한 값을 ret으로 빼낸다. 후에 push 0이 push OEP로 바뀌기 때문에 push한 OEP값을 ret으로 빼내서 OEP값으로 이동하는 뜻이다.RET C 이후 push 0과 ret 명령어를 확인할 수 있는데, 두 opcode에 BP를 걸고 프로그램을 실행한다.
이때 push 0이 push 10.445834로 변경된 것을 확인할 수 있는데, 이는 OEP인 0x445834를 push하고, ret에서 해당 주소로 이동한다는 뜻이다. 따라서 이곳이 OEP이다.
-> 해당 파일의 OEP는 0x445834이다.
여기까지 하면 모든 압축이 풀린 것을 확인할 수 있는데, 다음을찾기-모든모듈-문자열참조에서 “Registered... well done!” 문자열을 찾을 수 있는 것이 그 증거이다. (패킹된 상태에서는 찾을 수 없음)
→  445834 + 7555 = 4458347555가 답이다!
먼저 패킹의 원리는 다음과 같다.
- PUSHAD 명령어를 통해 레지스터를 스택에 쌓는다
 - 정상 코드를 메모리에 복구한다
 - POPAD 명령어를 통해 레지스터 값들을 복구한다
 - OEP로 분기한다.
 
따라서 1번을 실행한 후 스택에 저장된 레지스터에 하드웨어 브레이크포인터를 걸고 F9를 눌러 실행시킨다면, 해당 스택 값을 복원하려고 하는 3번 지점에서 BP가 걸릴 것이다.
PUSHAD를 실행했을 때, 스택에 레지스터들이 쌓인 것을 볼 수 있다.
그 중 한 개에 브레이크포인트를 걸고, F9를 눌러 실행한다.
POPAD 아래에서 BP가 걸려 멈추는 것을 알 수 있다. 그 아래에 있는 0x445834가 OEP이고, 이곳을 지나 ret하면 언패킹이 완료된다!
언패킹 루틴을 지났고 함수의 프롤로그가 보이는 것으로 보아 언패킹이 완료된 것을 알 수 있다. 이 상태에서 덤프를 뜨는 방법을 알아보자.
메모리 덤프를 위해 x64dbg 메뉴의 Scaylla를 클릭한다.
Scaylla를 클릭해서
1. IAT Autosearch를 클릭한다
2. Get Imports를 클릭한다
3. Dump를 클릭하고 원하는 경로에 새로운 파일로 저장한다
4. Fix Dump를 클릭하고 저장한 파일을 Fix한다
Fix Dump를 하는 이유는?최종적으로 덤프한 언패킹된 파일을 x64dbg에서 열어보았다. 성공적으로 덤프된 것을 확인할 수 있다.
RET C를 찾고 OEP를 찾는 방법에서 '등록성공'으로 가는 분기점을 찾은 방법과 완전히 같다.
ASPack를 처음 접해봐서 RET C를 찾으면 언패킹할 수 있다는 건 어디서 알 수 있는 건지 궁금했는데, 검색해보니 관련 자료를 찾을 수 있었다. 아래에서 여러 패커들을 수동으로 패킹하는 방법들을 소개하고 있다.