728x90

OEP 


OEP는 Orignal Entry Point로 EP는 엔트리 포인트이다.

엔트리 포인트는 운영체제가 사용자 프로그램으로 최초로 제어를 넘기는 지점으로 실행 코드가 최초로 실행되는 지점이다. 이런 OEP 를 찾는 방법은 여러 가지가 있다. 이러한 방법들에 대해 복습 겸 자세히 알아보고자 한다.

 

1. EP 값 찾기 

우선적으로 EP 값을 찾아야 한다. EP의 값은 AddresssOfEntryPoint 값과 ImageBase 값을 더하면 된다.

AddresssOfEntryPoint + ImageBase = EP

EP의 주소값을 찾아내면 그 주소에 EP를 설정한다.

 

2. 디코딩 루프

모든 패커에는 디코딩 루프(Decoding Loop)가 존재한다. 압축/해제 알고리즘 자체가 낳은 조건 분기와 루프로 구성되어 있다는 걸 알고 있다면 디코딩 루프가 왜 그리 복잡해 보이는지 이해할 수 있다.

이러한 디코딩 루프를 디버깅 할 때는 조건 분기를 적절히 건너 뛰어가며 루프를 탈출해야 한다. 경우에 따라서는 한 눈에 루프가 보이지 않을 수도 있다. 레지스터의 변화를 잘 포착하는 것이 중요하다.

 

 

3.  IAT 새팅

일반적인 패커에서는 디코딩 루프가 끝나면 원본 파일에 맞게 IAT를 새롭게 구성한다.

UPack이 임포트 하는 2개의 함수 LoadLibraryA와 GetProcAddress를 이용하여 루프를 돌면서 원본 notepad의 IAT를 구성한다. notepad에서 임포트 하는 함수들의 실제 메모리 주소를 얻어서 원본 IAT 영역에 쓰는 것이다.

 

 

OEP 지점을 찾는 데 있어서 몇 가지 팁이 되는 요소들이 있다.

 

먼저 일반적으로 Decode 루틴 진입 전에 PUSHAD 를 해서 기존의 레지스터들을 백업한다. 그 다음은 POPAD 를 이용해서 레지스터들을 복구한다. 이러한 점을 이용해서 Hardware Breakpoint 로 해당 Stack 에 접근 시도하는 부분을 찾은 다음에 근처에 JMP 명령, Call 명령, 또는  PUSH 주소 RET 형태의 명령들을 유심히 살펴보자.

 

두번째는 IAT 에 LoadLibrary, GetProcAddress, VirtualProtect 정도의 함수만 있다. ASProtect 의 경우에는 OEP 로 점프하는 부분 근처에서 GetSystemTime 함수를 호출하는데 이 함수에 BP 를 걸어서 실행하면 2번의 호출 후에 OEP 로 점프하는 부분이 있다.

 

마지막으로 OEP 에는 원래의 Code 가 실행될텐데, Stub Code 가 등장하고 main 또는 WinMain 함수가 호출된다. Stub Code GetVersion(Ex), GetCommandLine(A/W) 함수를 호출하는데 해당 함수를 호출하는 부분에서 OEP 를 찾아본다.

 



+ Recent posts