본문 바로가기

2. Reversing (리버싱)/1) Write UP

[2021.09.25] abex crackme 5, PE파일

3.1 프로그램 동작 방식

파이로 만들어진 프로그램

델파이란?

델파이(Delphi)는 윈도우즈, 리눅스, iOS, 안드로이드에서 작동하는 프로그램 제작에 이용되는 통합개발환경이자 언어이다.

(프로그램을 실행시켰을 때의 화면)

 

3.2 GetVolumelnformation() 함수

 

GetVolumeInformation() 함수란?

지정된 루트 디렉터리가 속한 파일 시스템 정보와 볼륨 정보를 가져오는 함수.

 

3.3 반복문을 통한 문자열 변경

 

1. int i=2 : EDX 레지스터 하위 16비트를 의미하는 DL 레지스터에 2를 복사한다.

여기서 DL의 역할은? -> 반복문의 종료를 체크하는 변수

 

2. print(‘inside for loop’): 반복문이 수행하는 로직(logic)에 해당하는 부분.

 

3. i-- : DL 레지스터를 하나씩 감소시킴. DEC 명령어는 차감하는 대상이 0이 되면 제로 플래그를 1로 설정.

 

4. i>0 : 제로 플래그가 1이 아니면 004010AF로 점프.(반복문의 처음으로 다시 돌아가라)

만약 DL 레지스터가 0이 되면 제로 플래그가 1로 세팅되고 반복문은 종료하게 된다.

 

 

 

 

 

 

3.4 프로그램 구조 분석

1. 파일 시스템 정보와 볼륨 정보를 가져와서 일련번호를 만들기 위한 입력 값으로 사용.

 

2. 파일 시스템 정보와 프로그램 내부에 들어 있는 문자열을 결합해서 만든 새로운 문자열을 반복문을 통해 다른 문자열로 변형.(일련번호 생성 과정)

 

3. 앞에서 생성한 새로운 문자열을 가지고 프로그램 내부에 들어 있는 문자열과 결합해 일련번호 생성.

 

4. 생성한 일련번호와 사용자가 입력한 값이 일치하는지 확인. 일치할 경우 성공 메시지를 보여주고 다르면 오류 메시지를 보여줌.

 

3.5 문제 해결

 

주소 ‘004010D’에 브레이크 포인트 설정 후 실행.

 

주소 ‘0040109E’까지 이동.

 

나머지도 계속 한줄씩 실행시키면

반복문 실행 전

 

반복문 실행 후

문자열  OS4562-ABEX 가 입력되어서 반복문을 통해 문자열 QU6762-ABEX 가 출력.

 

1번 사진

1. 주소 ‘00402000’에 결합된 일련번호를 계속 저장한다.

 

2. 마찬가지로 결과를 주소 ‘00402000’에 저장한다.

 

2번 사진

 

3. 아까 입력한 값, 123을 확인할 수 있고 저장된 있음.

 

1번 사진 레지스터 값

EAX 레지스터에 주소 ‘00402000’ 이 저장된 것을 확인 할 수 있음. 이 주소에는 일련번호로 사용되는 문자열이 저장되어 있다.

 

 

2번 사진 레지스터 값

함수의 실행 결과는 EAX 레지스터에 저장되며 일련번호와 사용자가 입력한 값이 같으면 0, 다를 때는 1이 입력된다.

 

 

 

 

1. 비교문을 살펴보면 EAX 레지스터 값과 숫자 0을 비교. , 일련번호와 사용자가 입력한 값이 같은 때 제로 플래그를 1로 설정한다는 의미

 

2. 제로플래그가 1일 때 다음에 오는 주소로 점프함.

 

A3. PE 파일

3.1 PE 헤더

- PE 헤더의 가장 처음에 나오는 헤더 영역은 IMAGE_DOS_HEADER 이다. 이 헤더의 역할은 윈도우 운영체제의 하위 호환성을 지원하는 것.

 

- MS-DOS Stub Program DOS 운영체제에서 윈도우용 PE 파일을 실행했을 때 보여줄 오류 메시지를 저장. PE 파일 내부에는 이와 같은 오류 처리를 위한 작은 DOS 프로그램 이 내장.

 

- IMAGE_NT_HEADERS 4바이트 signature 2개의 IMAGE_FILE_HEADER, IMAGE_OPTIONAL_HEADER 구조체로 구성. 특히 IMAGE_FILE_HEADER 구조체 뒤에는 중요한 역할을 담당하는 16개의 IMAGE_DATA_DIRECTORY 구조체가 따라온다.

 

- IMAGE_FILE_HEADER에는 CPU종류, 섹션 수, 파일 생성 시간, Optional Header의 크기, 현재 파일의 형식 등 PE 파일에 대한 개략적인 정보가 들어있음.

 

- MAGE_OPTIONAL_HEADER의 항목

           1. Size of Code : 코드 영역의 크기를 나타냄.

           2. Address of Entry point : 엔트리 포인트를 가리킴.

           3. Base of Code : 코드 영역이 시작되는 주소(RVA)를 가리킴.

           4. Base of Data : 데이터 영역이 시작되는 주소(RVA)를 가리킴.

           5. Image Base : 메모리에 PE 파일이 저장되는 시작 주소.

           6. Section Alignment : 메모리에서 섹션 영역에 할당되는 최소 크기.

           7. File Alignment : PE 파일에서 섹션 영역에 할당되는 최소 크기.

           8. Number of Data Directories : 뒤에 오는 IMAGE_DATA_DIRECTORY 구조               체의 개수 지정

           9. IMAGE_DATA_DIRECTORY 영역 : 8바이트로 이루어진 구조체 배열

 

- IMAGE_DATA_DIRECTORY 구조체

           1. EXPORT Table : PE 파일에서 외부에 공개하고자 하는 함수 정보 저장

           2. IMPORT Table : PE 파일이 다른 라이브러리로부터 가져와 사용하는 함수 정보 저장

           3. RESOURCE Table : PX 파일에서 사용하는 리소스가 저장된 영역.

           4. BASE RELOCATION Table : PE 헤더에 있는 Image Base 값을 사용하지 못할 때 PE 파일 내부에 있는 절대 주소로 변경하는 데 사용되는 구조체.

           5. TLS Table : 엔트리 포인트 이전에 실행되는 함수를 지정할 때 사용.

           6. Import Address Table : Import Table과 깊은 관련이 있으며 리버싱에서 핵심적인 역할을 하는 구조체.

 

3.2 섹션 헤더

 

섹션 헤더에는 로더(Loeader)가 섹션 데이터를 메모리로 로딩하고 속성을 설정하는 데 필요한 정보가 저장되어 있음.

각각의 섹션 헤더는 IMAGE_SECTION_HEADER 구조체 형식으로 데이터를 저장하고 있음. 섹션 헤더에는 섹션 데이터를 사용하기 위한 기본 정보가 들어가 있음.

 

3.3 섹션 데이터

섹션 데이터에는 PE 파일에서 사용하는 각종 데이터들이 들어 있다.(실제로 프로그램을 실행하기 위한 데이터)

센션 데이터는 일정한 구조체 형식으로 데이터를 저장하지 않음. , PE헤더에서 지정한 구조체 형식으로 섹션 데이터의 특정 영역을 지정하면, 해당 영역에는 구조체 형태로 데이터가 조직화되어 저장됨.

 

4. IAT

- IAT?

실행 파일(PE 파일) 안에 어떤 라이브러리에서 어떤 함수를 가져다 쓰는지 기록해놓은 정보. 로더는 메모리로 로딩할 때 IAT에 기록된 API 이름을 참조해서 프로그램이 사용할 수 있는 주소를 찾아 IAT 안에 API를 가리키는 주소를 적어 놓음.

 

- IMAGE_IMPORT_DESCRIPTOR 구조체 배열로 이루어진 IMPORT Directory Table은 내부에 IAT에 대한 정보가 저장. IMAGE_IMPORT_DESCRIPTOR 구조체의 개수는 참조하는 DLL의 개수와 같음.

 

- IMPORT Directory Table INT  IAT에 대한 정보를 가지고 있음. INT  IAT PE 파일에서 사용하는 외부 라이브러리를 기록한 핵심 영역.

 

- PE 파일 상태에서는 IAT INT가 같은 값을 가지고 있지만, 로더가 PE 파일을 메모리로 로딩할 때 실제 참조해야 하는 주소값을 가지고 와서 IAT에 저장. PE 파일 내부에 있는 함수 이름을 가리키던 IAT 내부의 값은 함수를 가리키는 주소값으로 변경됨