009 Packer
I. Data Compression
i. Lossless Data Compression
: 압축된 파일 원래대로 복원 가능
: 데이터 크기가 줄어 보관 및 이동에 용이
: Run-Length, Lempel-Zic, Huffman 이용
ex) ZIP, RAR
i. Loss Data Compression
: 압축된 파일 원래대로 복원 불가능
: 데이터에 사람이 거의 알아차리지 못하는 정도의 의도적 손상을 주어 압축률 높임
: Run-Length, Lempel-Zic, Huffman 이용
ex) 멀티미디어 파일(jpg, mp3, mp4)
II. Run-Time Pack
: 실행 압축된 파일 내부에 압축 해제 코드가 포함돼있어 실행하는 순간 메모리에서 압축을 해제시킨 후 실행, 원본 PE 파일 + Decoding Routine(EP에서 실행)
III. Run-Time Packer
: 실행 파일 압축기, PE 파일 전문 압축기
> 패커 : 일반 PE 파일을 실행 압축 파일로 전환해주는 유틸리티
> 프로텍터 : Reverse Code Engineering으로부터 PE 파일을 보호하기 위한 유틸리티
: 크기 증가, 디버깅하기 어려움
: Anti-Reversing, Anti-Emulationg, Code Obfuscating, Polymorphic Code, Garbage Code, Debugger Detection 등의 리버싱 방지 기법들을 추가
: 크래킹 방지, 코드 및 리소스 보호
> 평범한 PE 파일 생성하는 패커 : UPX, ASPack 등
> 원본 파일 변형 및 PE 헤더 훼손시키는 패커 : UPack, PESpin, NSAnti 등
> 상용 프로텍터 : ASProtect, Themida, SVKP 등
> 공개용 프로텍터 : UltraProtect, Morphine 등
IV. PE Viewer
: PE 포맷 분석하여 보여주는 유틸리티
: PEView, Stud_PE(Upack도 잘 보임), PEID
V. UPX
: the Ultimate Packer for eXecutables
: 가장 잘 알려진 패커
: UCL 데이터 압축 알고리즘 사용
> OEP 찾는 방법
1. POPAD 명령어 이후 JMP에 BP 설치
2. 스택에 Hardware BP 설치
3. Ctrl+F8로 트레이싱하다 루프에 갇힐 경우 F12로 정지 후 루프 이후에 BP 걸고 F9 누른 후 다시 진행하다 모든 압축 해제가 끝난 후 JMP하는 부분 찾기
VI. UPack
: Ultimate PE Packer
i. How to pack
> Header 겹쳐쓰기 : MZ 헤더(IMAGE_DOS_HEADER)와 PE 헤더(IMAGE_NT_HEADERS) 겹쳐 써 헤더 공간 절약 및 복잡성 증가 → e_magic과 e_lfanew 확인
: 보통 e_lfanew는 MZ 헤더 크기(40h) + DOS Stub 크기(보통 A0h) = E0h이나, 값을 10h으로 설정
> SizeOfOptionalHeader 값 늘리기 : IMAGE_OPTIONAL_HEADER와 IMAGE_SECTION_HEADER 사이에 추가적인 공간을 확보하여 Decoding Code 추가
> IAMGE_OPTIONAL_HEADER.NumberOfRvaAndSizes 값 변경 : lMAGE_OPTONAL HEADER. NumberOfRvaAndSizes 값을 10h가 아닌 Ah로 변경하여, offset D8h의 LOAD_CONFIG Directory 이후의 사용되지 않는 IMAGE_DATA_DIRECTORY 영역에 코드 덮어쓰기
> IMAGE_SECTION_HEADER 덮어쓰기 : IMAGE_SECTION_HEADER 구조체 중 프로그램 실행에 영향을 주지 않는 항목들(offset to relocations, offset to line numbers, number of relocations, number of line numbers)에 코드 덮어쓰기
> 섹션 겹쳐쓰기 : 두 번째 섹션에 압축된 원본 섹션들 넣은 후, 첫 번째 섹션에 풀어 실행
> RVA to RAW : PointerToRawData값이 FileAlignment의 배수가 아니여서 원래 공식으로 구해지지 x → PointerToRawData를 강제로 FileAlignment의 배수에 맞춰 계산
ex)
> Import Table(IMAGE_IMPORT_DESCRIPTOR array) : 세 번째 섹션이 끝나는 주소 이후는 메모리에 매핑되지 않는데, 이 곳에 세 번째 섹션을 넣어 보이지 않게 하기
> IAT : DOS 헤더의 사용되지 않는 영역에 Import DLL name 넣어둠
* 008 IAT&EAT 포스팅 완료 후 필요 시 설명 추가 예정
ii. OEP
1. Stud_PE를 통해 ImageBase와 EP의 RVA값 얻어 EP의 VA 값 계산하여 해당 주소로 이동
2. Decoding Loop 풀기
3. IAT 세팅
* 해당 부분은 이후 악성 코드 분석 단계에서 Upack으로 패킹된 샘플 분석 후 정확하게 자세히 다시 기술할 예정
VII. ASPack
> 패킹 : Section 수 증가, IMAGE_OPTIONAL_HEADER 변경, 모든 섹션 메모리에 쓰기가 가능하도록 Characteristics 추가
> OEP : RETN 0C 검색하여 해당 주소에 BP 걸고 실행하여 해당 주소로 넘어가기
VIII. PESpin
> 패킹 : 순수 Assem, garbage 섹션 추가, 섹션 이름 변경, Jumping into the middle of an instruction, Breaking Code Alignment