UPack 으로 실행 압축된 파일은 여러가지 특징을 가진다.


1. MZ헤더와 PE헤더를 겹쳐 쓴다.

- IMAGE_DOS_HEADER.e_lfanew 값을 10으로 설정


2. SizeOfOptionalHeader

- 값을 148로 변경 (PE32에서 크기는 E0)

- IMAGE_OPTIONAL_HAEDER 시작 옵셋에 SizeOfOptionalHeader 값을 더한 위치부터 IMAGE_SECTION_HEADER가 나타난다.

- 실제 구조체 크기를 제외한 공간에 디코딩에 필요한 코드를 넣기위함


3. NumberOfRvaAndSizes 

- 값을 A로 설정 (원래는 10)

- 나머지 항목에 디코딩 코드를 넣기위함


4. 섹션 겹쳐쓰기

- 첫 번째 섹션과 세 번째 섹션의 파일 시작 옵셋과 파일에서의 크기가 완전히 동일하다.

- 그러나 메모리에서의 시작 RVA와 크기(VirtualSize)는 다르다.

- 두 번째 섹션에 압축된 원본파일이 있고, 첫 번째 섹션에 원본파일을 압축해제한다.


5. PointerToRawData

- 값을 10으로 설정

- 일반적으로 PointerToRawData값은 FileAlignment값의 배수가 되어야한다.

- PE로더는 PointerToRawData값이 FileAlignment값의 배수가 아니면 강제로 배수에 맟춰서 인식한다.

- 그러나 PE유틸리티들은 PointerToRawData값을 그대로 신뢰했기 때문에 에러가 발생했었다.


6. 특이한 Import Table 구성

- IMAGE_IMPORT_DESCRIPTOR 구조체 배열중 첫 번째 구조체는 정상, 그 뒤로는 두 번째 구조체도 아니고, 끝을 알리는 NULL 구조체도 아니다.

- 하지만 메모리에 로딩시, Import Table의 마지막 2바이트부터 Import Table이 속하는 세 번째 섹션에 매핑되지 않고 NULL로 채워진다.

- 즉 첫 번째 구조체는 정상 IID 구조체가 되고, 나머지는 NULL이 채워지기 때문에 구조체의 끝을 알리는 NULL 구조체가 된다.

- 쉽게 말하면 파일과 프로세스의 섹션 범위가 달라서 파일에서는 Import Table이 아닌것 처럼 보이지만 메모리 로딩시 정상 Import Table이 된다.

+ Recent posts