-
15 UPX 실행 압축된 notepad 디버깅리버싱 엔지니어링/리버싱 핵심 원리 2022. 3. 27. 02:31
notepad.exe의 EP code
: notepad.exe를 OllyDbg로 open
- 010073B2 주소에서 GetModuleHandleA() API 호출하여 notepad.exe 프로세스의 ImageBase를 구한다
- ImageBase : PE 파일이 로딩되는 시작 주소
- GetModeuleHandleA() : 인자로 모듈 이름(dll,exe)을 넘겨주면 해당 모듈의 핸들, 베이스 주소를 리턴한다
- 성공시 핸들, 실패시 NULL 리턴
- 인자를 NILL로 전달하면, 호출 프로세스(.exe 파일)를 만드는 데 사용된 파일에 대한 핸들을 반환.
- 번외) GetModuleHandle(NULL)을 hinstance를 구한다고도 함
- hinstance : 운영체제가 메모리에서 로드될 때 프로그램을 식별 위해 갖는 ID값
- hinstance 핸들은 보통 메모리 상 올라가있는 시작주소 값을 갖고 있다.
- 010073B4 주소에서 MZ 비교, 010073C0 주소에서 PE 시그니처 비교
- MZ, PE 시그처란?
- 리틀엔디언 표기법 주의!
- 모든 PE 파일은 시작 부분에 DOS signature("MZ")가 존재 : 4D5A
- 리틀엔디언 표기법으로 인해 코드내에서 5A45와 비교
- (참고) e_ifanew : NT header의 옵셋 = 000000E0
- PE signature(PE00) : 5045
- 리틀엔디언 표기법으로 인해 코드내에서 4550와 비교
- MZ, PE 시그처란?
notepad_upx.exe의 EP code
: notepad_upx.exe를 OllyDbg로 open
파일이 압축된 경우 나오는 알림창. 아무거나 선택해서 넘어가기
- 섹션 시작 주소(Image Base 고려)
- 첫 번째 : 01001000
- 두 번째 : 01011000
- 세 번째 : 01016000
- 첫 번째 : 01001000
- upx EP 코드
- EP 주소는 01015330 이며, 두번째 섹션의 끝부분. 실제 압축된 원본코드의 EP 주소(0100739D) 위쪽으로 존재
- PUSHAD 명령으로 EAX~EDI 레지스터 값을 스택에 저장
- ESI와 EDI 레지스터를 각각 두번째 섹션 시작 주소(01011000)와 첫번째 시작주소(01001000)로 세팅
- 디버깅 시, ESI와 EDI가 동시에 세팅되면 ESI가 가리키는 버퍼에서 EDI가 가리키는 버퍼로 메모리 복사가 일어날 것으로 예측 가능
- 이 경우에서는 Sourece(ESI)로 부터 데이터를 읽어 압축해제 후 Destination(EDI)에 저장
- UPX EP 코드를 전부 쫓아가(트레이싱) 원본 EP 코드를 찾아내는것
- 리버싱에서는 원본 EP를 OEP(Original Entty Point)라고 한다.
UPX 파일 트레이싱
트레이싱할 때의 원칙 : "루프(loop)를 만나면 그 역할을 살펴본 후 탈출한다."
OllyDbg 트레이스 명령어
명령어 단축키 설명 Animate Into Ctrl+F7 Step Into 명령 반복(화면 표시 O) Animate Over Ctrl+F8 Step Over 명령 반복(화면 표시 O) Trace Into Ctrl+F11 Step Into 명령 반복(화면 표시 X) Trace Over Ctrl+F12 Step Over 명령 반복(화면 표시 X) - 애니메이트 명령어는 트레이싱 과정이 화면에 표시되어 속도가 느림
- 트레이스 명령어는 미리 설정한 트레이스 조건에서 자동으로 멈출 수 있고, 로그를 남길 수 있음
- UPX 파일 트레이싱 에서는 Animate Over[Ctrl+F8] 사용
루프 #1
EP code에서 Animate Over[Ctrl+F8] 사용
→ 짧은 루프가 나타남, 트레이싱을 멈추고(Strp Into[F7]) 해당 루프 확인
- 루프 회전수 ECX는 350 이상(루프 중간에 멈췄기 때문)
- EDX에서 한바이트를 읽어 EDI에 쓰는 것
- 실행 압축 파일 디버깅 시 이러한 루프를 만나면 루프를 빠져나와야함
- 루프 다음 주소인 010153E6에 BP 설치후 실행하여 루프 탈출
루프#2
- 본격적인 디코딩(decoding) 루프 또는 압축해제 루프.
- ESI가 가리키는 두번째 섹션(UPX1)의 주소에서 차례대로 값을 읽어서 적절한 연산을 거쳐 압축을 해제하여 EDI가 가리키는 첫번째 섹션(UPX0)의 주소에 값을 써줌
- 사용되는 명령어들( AL(EAX)에는 압축해제된 데이터가 존재, EDI는 첫 번째 섹션의 주소 )
- 이전과 동일하게 BP 설치 후 실행하여 루프 탈출
루프 #3
다시 트레이싱, 아래와 같은 루프 발견
- 원본 코드의 CALL/JMP 명령어의 destination 주소를 복원해주는 코드
- 01015434 주소에 BP 설치 후 탈출
+) 일반적으로 실행 압축파일은 원본 파일 코드, 데이터, 리소스 압축해제 과정이 끝나면 IAT*(Import Address Table)를 세팅하고 OEP로 이동 -> IAT 세팅만 하면 UPX 압축해제 코드 끝!
*IAT : 프로그램이 어떤 라이브러리에서 어떤 함수를 사용하고 있는지를 기술한 테이블
루프 #4
다시 트레이싱하면, IAT 세팅하는 루프 발견
- 01015436 주소에서 EDI=01014000으로 세팅, 이곳은 두번째 섹션(UPX1)
- 이곳에 notepad.exe에서 사용되는 API 문자열이 저장되어있음
- GetProcAddress() 호출
- GetProcAddress() : DLL에 있는 API 주소를 가져옴
- API 시작주소를 얻어 EBX 레지스터가 가리키는 notepad.exe IAT 영역에 API 주소를 입력.
- 루프 탈출 후 실행하면, OEP로 점프하는 코드 발견(JMP 0110739D)
↓0110739DUPX의 OEP 빨리 찾는 방법
POPAD 명령어 이후의 JMP 명령어에 BP 설치
- UPX 패커의 특징은 EP코드가 PUSHAD/POPAD로 둘러싸여 있는것
- OEP 코드로 가는 JMP 명령어가 POPAD 바로 이후에 나탸난다.
스택에 하드웨어 브레이크 포인트 설치
- PUSHAD 명령을 실행 후, ESP에 저장된 스택 주소로 이동
- 이동 후 하드웨어 BP 설치
- BP가 설치된 명령어가 실행된 이후에 제어를 멈춘다
- 실행하면, 압축이 해제되면서 코드가 실행되고, POPAD가 호출되는 순간 제어가 멈춤.
- OEP로가는 JMP 명령어 발견 가능
'리버싱 엔지니어링 > 리버싱 핵심 원리' 카테고리의 다른 글
17 실행 파일에서 .reloc 섹션 제거하기 (0) 2022.03.27 16 Base Relocation Table (0) 2022.03.27 14 실행 압축 (0) 2022.03.25 13 PE File Format(5) - EAT (0) 2022.03.24 13 PE File Format(4) - IAT (0) 2022.03.23 - 010073B2 주소에서 GetModuleHandleA() API 호출하여 notepad.exe 프로세스의 ImageBase를 구한다