이번글 부터는 섹션에 대해서 알아 볼 차례이다.

섹션헤더 영역에는 각 세션의 헤더들이 있는데 섹션들은 이 헤더에 메타데이터를 저장하고 있고, 메모리에 로드 될 때 필요한

정보를 저장하고 있다.

섹션헤더의 구조체 형태는 다음과 같다.

[그림 1 - IMAGE_SECTION_HEADER 구조체 형태]

위 이미지에는 없지만 IMAGE_SIZEOF_SHORT_NAME 은 8바이트로 정의되어 있으며, 이름의 길이가 8바이트를 넘어가게 되면

8바이트 이후로는 잘리며, 8바이트가보다 짧을 경우 남는 공간은 NULL로 채워지게 된다.


아래는 notepad.exe의 .text 섹션의 헤더 영역이다. 각 섹션들도 같은 구조이기 때문에 .text섹션을 예를 들어 각 구조체

멤버들을 표시 한 것이다.

[그림 2 - IMAGE_SECTION_HEADER 구조체멤버 표시]

 - Name : 섹션의 이름부분으로, 8바이트 내에서 사용자가 임의로 수정 가능하며, 위에서 설명한 성격을 지니고 있다.

 - VirtualSize : 메모리에 로드 되는 섹션의 전체 크기이다. 이 필드는 실행파일에서만 존재하고 오브젝트 파일에서는 0으로
                     설정되어 있고, SizeOfRawData 보다 크다면 섹션의 나머지 부분은 0으로 채워진다. 크기는 4바이트이다.

 - VirtualAddress : 메모리에 로드 되었을 때의 RVA 값을 가지고 있다. 오브젝트 파일의 경우 0으로 설정된다.
                           크기는 4바이트 이다.

 - SizeOfRawData : 실행 파일의 경우 디스크 상에서 초기화된 데이터의 크기를 말하며, Optional Header의 FileAlignment 값의
                             배수이어야 하고, VirtualSize보다 작다면 섹션의 나머지 부분은 0으로 채워진다. 오브젝트 파일의 경우
                             0으로 설정된다. 크기는 4바이트 이다.

 - PointerToRawData : PE 파일 내에서의 섹션 위치의 오프셋을 값으로 가지고 있다. 실행파일의 경우 이 값은 무조건
                                FileAlignment의 배수여야 한다. 크기는 4바이트 이다.

 - PointerToRelocations : 섹션 재배치에 대한 시작 지점 오프셋을 값으로 가지고 있다. 이 값은 보통 오브젝트 파일에
                                     사용되며, 실행파일의 경우 0으로 설정된다. 크기는 4바이트 이다. 위 이미지에서도 보이다 싶이
                                     notepad.exe는 실행파일이어서 0으로 셋팅되어 있다.

 - PointerToLinenumbers : 해당 섹션에 대한 Line-number 엔트리의 시작 지점 주소값을 가지고 있다. Line-number 엔트리는
                                      COFF 포맷으로 지금은 사용하지 않기 때문에 0으로 설정되어 있다.

 - NumberOfRelocations : 해당 섹션의 재배치 엔트리 숫자를 값으로 가지고 있다. 실행 파일의 경우 항상 0으로 설정되어 있다.

 - Characteristics : 해당 섹션의 속성 정보를 표시하는 값을 가지고 있다. 위 이미지에서 경우 "0x60000020" 이라는 값을
                            가지고 있는데, 이 값은 "0x40000000", "0x20000000", "0x00000020" 이라는 값이 합쳐진 값이다.
                            해당 값들에 대한 속성정보는 아래와 같다.

[그림 3 - 속성 목록표]

더 많은 속성들이 있지만 이 글 특성상 다 표시할 필요는 없을 것 같아 중요한 것만 목록화 하였다.

더 많은 속성들을 보기 원한다면 WinNT.h 파일을 참조하기 바란다.

만약 섹션의 이름이 임의로 바꿔져 어떠한 섹션인지 파악이 안된다면 섹션 속성정보를 보는것도 하나의 방법이다.

섹션 속성정보들은 각 섹션마다 기본적으로 정의되어 있어 섹션 속성정보만 봐도 어떠한 섹션인지 파악이 가능하다.

 

 

'[+] Information > [-] RCE' 카테고리의 다른 글

PE 구조 (8)  (0) 2012.01.01
PE 구조 (7)  (0) 2012.01.01
PE 구조 (6)  (0) 2011.12.31
PE 구조 (5)  (0) 2011.12.31
PE 구조 (4)  (0) 2011.12.30
이번에는 IMAGE_DATA_DIRECTORY 구조체를 알아볼 차례이다.

WinNT.h를 보면 IMAGE_OPTIONAL_HEADER안에 있지만, 사실은 NT Additional Fields 하부구조체이다.

구조는 아래와 같다.

[그림 1 - 구조체 형태]


WinNT.h에 명시되어 있는 것을 보면 IMAGE_DATA_DIRECTORY의 엔트리 개수는 16개로 정의되어 있다.

[그림 2 - 엔트리 정의]

 
엔트리는 다음과 같이 정의되어 있고, 마지막은 0으로 예약되어 있기 때문에 16개가 되는 것이다.

 [그림 3 - 엔트리 목록]

아래는 notepad.exe의 IMAGE_DATA_DIRECTORY 구조체의 각 엔트리 부분을 표시한 것이다.

표시한 각 부분의 앞쪽 4바이트는 RVA(DWORD VirtualAddress)이며, 뒤쪽 4바이트는 크기(DWORD Size)를

의미한다. 


 [그림 4 - notepad.exe 엔트리 표시]

각 부분에 대한 설명은 주소와 크기로만 나누어지기 때문에 생략하도록 하겠다. 

'[+] Information > [-] RCE' 카테고리의 다른 글

PE 구조 (7)  (0) 2012.01.01
PE 구조 (6)  (0) 2011.12.31
PE 구조 (5)  (0) 2011.12.31
PE 구조 (4)  (0) 2011.12.30
PE 구조 (3)  (0) 2011.12.30
이번에는 PE 헤더 영역에 3번째 부분인 PE File Optional Header 부분에 대해 알아 볼 차례이다.

[PE File Optional Header]
이 부분은 실행파일의 실행정보가 담긴 부분이며, 필수적인 부분이어서 PE File Header 부분보다 더 중요시 된다.
Option이라는 이름이 붙은 이유는 오브젝트가 이 영역을 선택적으로 가질 수 있기 때문인데, 정작 오브젝트에서는 별다른 기능을 발휘하지 않는다.
PE File Optional Header 부분은 IMAGE_OPTIONAL_HEADER 구조체로 되어 있으며, 크기가 유동적이고 앞서 보았던
IMAGE_NT_HEADER의 SizeOfOptionalHeader 구조체멤버에 의해 크기가 결정 되며, PE File Header 바로 뒤에 위치해 있다. IMAGE_OPTIONAL_HEADER 구조체는 Standard Fields, NT additional Fields, IMAGE_DATA_DIRECTORY로 구분이 된다. 이제부터 3가지에 대해서 상세히 알아 볼 것이다. 


[Standard Fields]
파일을 로드하고 실행하는것에 대한 정보가 들어있다.
아래는 IMAGE_OPTIONAL_HEADER안에 있는 Standard Fields 영역에 구조이다.

[그림 1 - Standard Fields]


아래 notepad.exe 파일의 Standard Fields 영역을 보면서 각 구조체 멤버에 대해 설명하겠다.

[그림 2 - Standard Fields 영역의 구조체 멤버들 표시]


 - Magic : 실행 파일의 상태를 나타내는 부호없는 정수 값을 가지고 있으며, 이 값이 "0x010B" 라면 일반적인 실행 파일을
               뜻하는 것이고, "0x0107" 이라면 롬이미지, "0x020B" 라면 64bit Executable 타입이라는 것을 의미한다.
               오프셋은 0x00 ~ 0x01이며, 크기는 2바이트이다.
               위 이미지에서는 "0x010B" 값을 가지고 있으므로 일반 실행파일을 뜻하는 것을 알 수 있다.

 - MajorLinkerVersion : 링커의 상위 버전넘버를 저장하는 멤버이다. 오프셋은 0x02이며, 크기는 1바이트 이다.
                                  위 이미지에서는 "0x09" 라는 값을 가지고 있다.

 - MinorLinkerVersion : 링커의 하위 버전넘버를 저장하는 멤버이다. 오프셋은 0x03이며 크기는 1바이트 이다.
                                  위 이미지에서는 "0x00" 이라는 값을 가지고 있다. 

 - SizeOfCode : 코드 섹션(.text)의 크기 정보를 가지고 있으며, 코드 섹션이 여러개라면 그것들의 합에 대한 값을
                       가지고 있다. 오프셋은 0x04 ~ 0x07이며, 크기는 4바이트 이다.
                       위 이미지에서는 "0x0000A800" 의 값을 가지고 있다. 이 값은 10진수로 변환하면  "43008" 이 되므로
                       43008바이트의 크기를 가지고 있는 것이 된다.

 - SizeOfInitializedData : 초기화된 데이터 섹션의 크기를 값으로 가지고 있으며, SizeOfCode 멤버와 마찬가지로 자신이
                                    담당하고 있는 섹션의 수가 여러개라면 그들의 합에 대한 값을 가진다. 오프셋은 0x08 ~ 0x11
                                    이며, 크기는 4바이트 이다.위 이미지에서는 "0x00022400" 값을 가지고 있으며 10진수로
                                    변환시 "140288" 이 되므로 140288바이트의 크기를 가지고 있는 것이 된다.

 - SizeOfUninitializedData : 초기화되지 않은 데이터 섹션의 크기를 값으로 가지고 있으며, 섹션이 여러개 일시 위의
                                       구조체 멤버와 동일한 성격을 지닌다. 오프셋은 0x12 ~ 0x15이며, 크기는 4바이트 이다.
                                       위 이미지에서는 "0x00000000" 이라는 값을 가지고 있으며 이는 "0"을 뜻한다. 즉 초기화
                                       되지 않은 데이터가 없다는 뜻이 된다.

 - AddressOfEntryPoint : 메모리에 맵핑된 상태에서의 실행 코드 주소를 가지고 있다. 이 주소는 절대적인 주소가 아닌
                                    상대적인 주소(RVA)이며, 보통 .text 섹션 내의 특정 주소를 가리키게 된다. 실행 파일에서의
                                    이 주소는 실행 코드의 시작 주소이며, 디바이스 드라이버에서는 초기화 함수의 주소가 된다.
                                    반면 DLL 파일은 이 값이 선택적이며, 이 값이 없다면 반드시 0으로 되어야 한다. 오프셋은
                                    0x16 ~ 0x19 이며 크기는 4바이트 이다. 위 이미지에서는 "0x003689"라는 값을 가지고
                                    있다.

 - BaseOfCode : 실행 파일이 메모리에 맵핑된 상태에서의 코드섹션(.text) 주소를 가지고 있다. 이 값은 상대적 주소인
                         RVA 값이다. 오프셋은 0x20 ~ 0x23이며, 크기는 4바이트 이다. 위 이미지에서는 "0x00001000"
                         이라는 값을 가지고 있다.

 - BaseOfData : 실행 파일이 메모리에 맵핑된 상태에서의 데이터 섹션(.data) 주소를 가지고 있다. 이 값은 상대적 주소인
                        RVA 값이다. 오프셋은 0x24 ~ 0x27이며, 크기는 4바이트 이다. 위 이미지에서는 "0x0000C000"
                        이라는 값을 가지고 있다.


 위에서 RVA 라는 단어가 많이 나온다. 이쯤에서 RAV란 무엇인지 알고 가는 것이 좋을 것 같다.

[RVA(Relative Virtual Address)]
실행파일이 프로세스를 만들고 실행파일의 코드와 데이터가 가상메모리에 맵핑이되면 메모리에 맵핑되는 지점의 시작 주소가 베이스 주소(Base Address)가 된다. RVA는 이 가상 메모리상의 베이스 주소를 기준으로 로드된 실행 파일의 상대적인 위치를 의미한다. 가상메모리에서의 가상주소는 아래와 같은 형식으로 구할 수 있다.

가상 주소 = 베이스 주소(Base Address) + RVA
RVA는 가상 메모리에 맵핑된 이후의 오프셋 값이므로 PE 파일상의 오프셋과 같다고 생각하면 안된다.
물론 PE 파일은 가상메모리에 그대로 맵핑이 되어 순서가 맵핑 되기전과 같지만, 가상메모리에 맵핑이 되면 섹션 사이에
패딩이 생겨 오프셋값이 달라진다. 


이번에는 NT Additional Fields 영역을 알아볼 차례이다.

[NT Additional Fields]
이 영역은 Standard Fields 바로 다음부터 시작되며, 많은 구조체 멤버로 이루어져 있다.
이 영역에서 제공되는 정보는 윈도우 링커와 로더가 사용하는 정보다.
아래는 해당 영역의 구조이다.

[그림 3 - NT Additional Fields]

링커와 로더가 사용하는 정보다 보니 32bit 실행 파일과 64bit 실행 파일의 오프셋이 조금 다르다.
아래 이미지는 32bit 실행 파일이므로 참고하기 바란다.(같은 구조체이기 때문에 오프셋은 계속 이어감)

[그림 4 - NT Additional Fields의 구조체 멤버들 표시]

 - ImageBase : 가상메모리에 로드된 실행 파일의 주소를 가지고 있다. 이 값은 반드시 64KB의 배수여야 한다. 오프셋은
                       0x28 ~ 0x 31이며, 크기는 4바이트 이다. 위 이미지에서는 "0x01000000" 이라는 값을 가지고 있다.
* 참고 : ImageBase 구조체 멤버값과 Standard Fields의 BaseOfCode값을 더하면 .text 가상메모리 주소다

 - SectionAlignment : 가상 주소에 맵핑 될 때 섹션이 할당 받을 가상 주소의 기준값을 가지고 있다. 섹션은 메모리에
                               맵핑 될 때 섹션별로 맵핑되기 때문이다. 섹션의 시작 주소는 항상 메모리 페이지의 배수여야 하므로
                               이 값은 FileAlignment와 같거나 커야 하며, 기본 값은 페이지의 크기와 같다. 오프셋은
                         0x32 ~ 0x35이며, 크기는 4바이트 이다. 위 이미지에서는 "0x00001000" 이라는 값을 가지고 있
                               다. 이 값이 BaseOfCode와 같은 것을 볼 수 있는데 이는 .text 섹션부터 메모리에 맵핑 된다는 것을
                               의미한다.

- FileAlignment : PE 파일 내에서 섹션들이 시작하는 주소의 기준 값이다. 따라서 PE 파일내에서의 섹션이 시작하는
                         주소는 항상 이 값의 배수가 된다. 이 값은 2에서 512사이에 있는 2의 멱승이거나 64KB가 되지만
                         기본값은 512이다. SectionAlignment의 값이 메모리 페이지 크기보다 작다면 FileAlignment의
                    값과 동일하여야 한다.
 오프셋은 0x36 ~ 39이며, 크기는 4바이트 이다. 위 이미지에서는
                    "0x00000200" 값을 가지고 있는데 이 값을 10진수로 변환하면 512가 된다. 기본 값을 가지고 있다는
                         뜻이 된다. 

 - MajorOperatingSystemVerison : 실행 파일을 실행하는데 필요한 OS의 최소 상위버전의 값을 가지고 있다.
                                                  오프셋은 0x40 ~ 0x41이며, 크기는 2바이트 이다. 위 이미지에서는 "0x0006"
                                                  이라는 값을 가지고 있다.

 - MinorOperatingSystemVersion : 실행 파일을 실행하는데 필요한 OS의 최소 하위버전의 값을 가지고 있다.
                                                  오프셋은 0x42 ~ 0x43이며, 크기는 2바이트 이다. 위 이미지에서는 "0x0001"
                                                  이라는 값을 가지고 있다.

 - MajorImageVersion : 실행파일의 상위버전의 값을 가지고 있다. 오프셋은 0x44 ~ 0x45이며, 크기는 2바이트 이다.
                                  위 이미지에서는 "0x0006" 이라는 값을 가지고 있다. 

 - MinorImageVersion :  실행파일의 하위버전의 값을 가지고 있다. 오프셋은 0x46 ~ 0x47이며, 크기는 2바이트 이다.
                                   위 이미지에서는 "0x0001" 이라는 값을 가지고 있다. 

 - MajorSubsystem : 실행 파일을 실행하는데 필요한 서브시스템의 상위버전의 값을 가지고 있다. 오프셋은
                               0x48 ~ 0x49이며, 크기는 2바이트 이다. 위 이미지에서는 "0x0006" 이라는 값을 가지고 있다.

 - MinorSubsystem : 실행 파일을 실행하는데 필요한 서브시스템의 상위버전의 값을 가지고 있다. 오프셋은 
                               0x50 ~ 0x51이며, 크기는 2바이트 이다. 위 이미지에서는 "0x0001" 이라는 값을 가지고 있다.

 - Win32VersionValue : 이 멤버는 VC++6.0 SDK까지는 예약 영역이었으며 7.0부터 지금의 이름으로 바뀌었다. 하지만
                                  여전히 사용하지 않아 보통 0으로 되어있다. 오프셋은 0x52 ~ 0x55이며, 크기는 4바이트 이다.
                                  위 이미지에서는 0의 값을 가지고 있다.

 - SizeOfImage : 메모리에 로드되었을 때 실행 파일의 크기 값을 가지고 있다. 이 값은 헤더를 포함했을 때의 크기이며,
                         반드시 SectionAlignment의 배수여야 한다. 이 값을 기준으로 해서 가상 메모리에서 실행 파일을
                         맵핑할 공간을 예약한다.
                         오프셋은 0x56 ~ 0x59이며, 크기는 4바이트 이다. 위 이미지에서는 "0x00030000" 이라는 값을
                         가지고 있다.

 - SizeOfHeader : DOS Stub, PE 헤더, 섹션 헤더의 합 값을 가지고 있다. 이 값은 무조건 FileAlignment의 배수여야
                          한다. 오프셋은 0x60 ~ 0x63이며, 크기는 4바이트 이다. 위 이미지에서는 "0x00000400" 값을
                          가지고 있다.

 - Checksum : 실행 파일의 체크섬 값을 가지고 있다. 체크섬 알고리즘은 IMAGEHELP.DLL 파일에 있으며 이 값은 모든
                      드라이버와 부팅시 로드된 DLL 파일, 중요한 윈도우 프로세스가 로드한 DLL 파일을 검증 할 때 사용된다.
                      오프셋은 0x64 ~ 0x67이며, 크기는 4바이트 이다. 위 이미지에서는 "0x00039741" 이라는 값을 가지고
                      있다.

 - Subsystem : 실행 파일을 실행하는데 필요한 서브 시스템의 값을 가진다. 오프셋은 0x68 ~ 0x69이며, 크기는
                       2바이트 이다. 위 이미지에서는 "0x0002" 라는 값을 가지고 있다. 목록표에 따르면 Windows GUI
                       서브시스템을 뜻한다. 아래는 Subsystem 값 목록표이다.

[그림 5 - Subsystem 값 목록표]

 - DllCharacteristics : PE 파일이 DLL 파일인 경우 파일의 속성 정보를 의미한다. 오프셋은 0x70 ~ 0x71이며, 크기는
                         2바이트 이다. 위 이미지에서는 "0x8140" 이라는 값을 가지고 있다.

 - SizeOfStackReserve : 예약할 스택의 크기 값을 가지고 있다. 오프셋은 0x72 ~ 0x75이며, 크기는 4바이트 이다.
                                   위 이미지에서는 "0x00040000" 이라는 값을 가지고 있다.

 - SizeOfStackCommit : 커밋할 스택의 크기 값을 가지고 있다. 오프셋은 0x76 ~ 0x79이며, 크기는 4바이트 이다.
                                   위 이미지에서는 "0x00011000"이라는 값을 가지고 있다.

 - SizeOfHeapReserve : 예약할 힙의 크기 값을 가지고 있다. 오프셋은 0x80 ~ 0x83이며, 크기는 4바이트 이다.
                                   위 이미지에서는 "0x00100000" 이라는 값을 가지고 있다. 

 - SizeOfHeapCommit : 커밋할 힙의 크기 값을 가지고 있다. 오프셋은 0x84 ~ 0x87이며, 크기는 4바이트 이다.
                                  위 이미지에서는 "0x00001000" 이라는 값을 가지고 있다.

 - LoaderFlags : 예약된 영역으로 0으로 채워져 있다. 오프셋은 0x88 ~ 0x91이며, 크기는 4바이트 이다.
                        위 이미지에서는 0 값을 가지고 있다. 

 - NumberOfRvaAndSize : Optional Header의 나머지 부분에 있는 데이터 디렉터리 엔트리의 숫자 값을 가지고 있다.
                                      오프셋은 0x92 ~ 0x95이며, 크기는 4바이트 이다. 위 이미지에서는 "0x00000010" 값을
                                      가지고 있다. 



글이 많이 길어진 관계로 나머지 한 부분인 IMAGE_DATA_DIRECTORY 구조체는 다음 글에서 다루도록 하겠다.

'[+] Information > [-] RCE' 카테고리의 다른 글

PE 구조 (6)  (0) 2011.12.31
PE 구조 (5)  (0) 2011.12.31
PE 구조 (4)  (0) 2011.12.30
PE 구조 (3)  (0) 2011.12.30
PE 구조 (2)  (0) 2011.12.29
이제부터 알아 볼 PE 영역은 PE 파일의 시작 부분이라고 할 수 있는 PE Header 영역이다.

PE Header 영역에는 PE File Signature, PE File Header, PE File Optional Header 영역이 있다.

PE Header 영역은 IMAGE_NT_HEADERS 구조체로 이루어져 있는데 구조체 정보는 다음과 같다.

[그림 1 - IMAGE_NT_HEADERS 구조체 정보]

위에 정의된 구조체는 64bit 구조체이며 아래는 32bit 구조체이다.

어느정도 직관적인 구조체 멤버이름을 통해서 왜 PE 헤더영역이 3가지로 나누어 졌는지 알 수 있다.

이제부터 PE 헤더 영역을 구성하고 3가지 영역에 대하여 알아 볼 것이다.

[PE File Signature]
이 영역은 DOS의 e_magic 구조체멤버처럼 PE 영역의 시작을 알리는 값을 가지고 있는 영역이다. 모든 파일에서 그 값은 항상 동일하며 그 값은 "PE/0/0(0x50/0x45/0x00/0x00)" 이다.
이 Signature 값 또한 메모리나 파일시스템 분석에서 삭제된 실행파일을 찾는데에 중요한 단서가 된다. 
아래는 notepad.exe 파일의 PE File Signature 값을 보여주는 이미지이다.

[그림 2 - PE File Signature 영역]

여기서 참고로 봐둘 점이 있다. 이전 글에서 설명했다 싶이 DOS MZ HEADER 영역의 e_lfanew 구조체멤버는 IMAGE_NT_HEADER의 주소를 가지고 있다고 설명하였는데 여기서 그 사실을 확인 할 수 있다.


[PE File Header]
이 영역은 실행 파일 자체의 메타데이터를 가지고 있으며, 길이는 20바이트이다.
구조체는 IMAGE_FILE_HEADER 구조체를 사용하며, 구조체 정보는 아래와 같다.

[그림 3 - IMAGE_FILE_HEADER 구조체 정보]


아래는 notepad.exe의 PE File Header 영역인데 이것을 가지고 각 구조체 멤버에 대해서 설명하겠다.

[그림 4 - PE File Header 영역]

 - Machine : 해당 구조체 멤버는 실행 파일이 사용하는 CPU를 나타내는 번호를 가지고 있다.
                   오프셋은 0이며, 크기는 2바이트이다. 위 이미지에서는 i386을 뜻하고 있는 "0x014C"를 가지고 있다.
 - NumberOfSections : 해당 구조체 멤버는 실행파일이 가지고 있는 섹션의 개수를 의미하며, 오프셋은 2이고, 크기는
                                 2바이트이다. 위 이미지에서는 "0x0004"를 가지고 있어 섹션의 개수가 4개라는 것을 알 수 있다.
                                 만약 섹션의 삭제, 추가를 하게 되면 이 구조체 멤버의 값 또한 변경해줘야 한다.
 - TimeDataStamp : 실행파일이 컴파일 된 시가으로 이 시간은 컴파일한 컴퓨터의 시스템 시간을 의미한다. 32비트
                             유닉스 포맷으로 GMT를 기준으로 한다. 위 이미지에서는 "0x4A5BC60F" 값을 가지고 있으며,
                             이 값을 10진수로 변환하였을 경우 "1247528463" 라는 숫자가 되며 이 숫자를 우리가 알아 볼 수
                             있는 날짜로 변환하면 아래와 같다.

[그림 5 - Python을 이용하여 변환]

 - PointerToSymbolTable : COFF 심볼 파일의 오프셋을 값으로 가지고 있다. 이 부분은 컴파일러에 의해 생성된 OBJ
                                       파일이나 디버그 모드로 만들어져서 COFF 디버그 정보를 가진 PE 파일에서만 사용된다.
                                       COFF 심볼 테이블은 이제 더 이상 사용하지 않아 이 값은 반드시 0으로 설정되어야 한다.
                                       위 이미지에에서는 설명과 동일하게 "0"으로 셋팅되어 있다.

 - NumberOfSymbols : 심볼 테이블에 있는 엔트리 개수를 나타내며, COFF 심볼 테이블은 더 이상 사용되지 않으므로
                                 반드시 0으로 설정되어야 한다. 위 이미지에서는 설명과 동일하게 "0"으로 셋팅되어 있다.

 - SizeOfOptionalHeader : Optional Header의 크기를 값으로 가지고 있다. 이 값은 실행파일에서만 필요하다. 일반적으로
                                     32bit 시스템은 E0의 값을 가진다.
 - Characteristics : 파일의 속성을 결정하는 값을 가지고 있다. 위 이미지에서는 32비트 실행파일의 의미를 지닌 "0x0102"
                            값이 셋팅되어 있는 것을 볼 수 있다. 


나머지 하나인 PE File Optional Header는 다음 글에서 알아 볼 것이다.

아직 PE File Header 에 대한 설명이 남았고 참고 할 표도 있어 글이 너무 길어지는 것을 방지하기 위해 다음 글에서

다루기로 한다.

이번에는 포렌식 관점에서의 중요한 구조체멤버들을 되짚어 보자.

[포렌식관점에서의 구조체멤버]
현재 영역에서 모든 정보를 파악 할 필요는 없다. 중요한 내용만 보면 되는 것이다.
Machine 멤버의 경우 라이브 리스폰스나 메모리 분석등 다른 방법으로도 수집할 수 있는 정보이면서 중복되는 정보이므로, 보지 않아도 되고, Symbol 테이블에 관련된 멤버도 요즘에는 사용되지 않는 멤버이므로 보지 않아도 된다.

- TimeDateStamp : 파일의 생성시간에 대해 정보를 제공한다. 하지만 이 시간은 조작가능성을 배제할 수 없고, 다른
                            증거와 연결지어야 할 필요가 있다.
- SizeOfOptionalHeader : 해당 파일이 어느 시스템에서 만들어졌는가의 대한 정보를 제공한다. 요즘 도구들은 32, 64bit
                                    시스템의 분석을 지원하긴 하지만, 간혹 지원하지 못하는 경우가 있을 수 있어 이럴 경우 해당
                                    시스템에 맞는 분석도구를 사용하여야 한다. 그렇기에 반드시 확인 해 볼 필요가 있다.
- Characterstics : 해당 파일의 속성이 어떤 것인지에 대한 정보를 제공한다. 특히 exe와 dll 파일을 구분 할 때 유용하다.
                          파일카빙을 하였을 경우 해당 파일이 어떤 파일인지 구분이 가지 않으므로, 이 부분을 확인하면 어떤
                          파일인지 알 수 있을 것이다.


[참고]
* Machine 멤버에서의 값 목록표

[그림 6 - Machine 값 목록표]

* Characterstics 속성 목록표

 [그림 7 - Characterstics 값 목록표]

참고로 위 notepad.exe에서 Characterstics 값이 0x0102 였는데 이건 IMAGE_FILE_32BIT_MACHINE의 값과

IMAGE_FILE_EXECUTABLE_IMAGE 값이 합쳐진 것이다. 

'[+] Information > [-] RCE' 카테고리의 다른 글

PE 구조 (5)  (0) 2011.12.31
PE 구조 (4)  (0) 2011.12.30
PE 구조 (3)  (0) 2011.12.30
PE 구조 (2)  (0) 2011.12.29
PE 구조 (1)  (0) 2011.12.29
이번 글에서 알아볼 PE 구조의 영역은 DOS 영역이다.

이 영역은 윈도우 실행 파일을 DOS 모드에서 실행하려고 할 때 사용자에게 에러 메시지를 보여주기 위해 존재한다.

실제로 이 영역은 윈도우 실행파일이 윈도우에서 실행할 때에는 아무런 영향을 주지 않는 부분이어서 볼만한 내용이 많지는

않다.

DOS MZ Header와 DOS Stub Program 영역으로 이루어져 있는 이 DOS 영역에 대해서 자세히 알아보자.

[DOS MZ Header]
이 영역은 WinNT.h 헤더파일에 정의되어 있으며, 영역의 구조부터 알아보면 아래와 같다.

[그림 1 - DOS MZ Header의 구조체 구조]

여기서 눈여겨 볼 구조체 멤버는 e_magic과 e_lfanew 구조체 멤버이다.
다른 구조체 멤버들은 사용하지 않거나 PE 파일포맷 내에서는 사실상 의미가 없는 것들이다.

 - e_magic : 이 구조체 멤버는 DOS MZ Header의 맨 앞(PE 파일 맨 앞)을 나타내며 16진수로는 "4D 5A" 값을 가지고
                   아스키코드로 변환하면 "MZ" 라는 값을 가진다. 참고로 MZ는 도스를 최초로 설계한 사람 중 한명인
                   Mark Zbikowksi의 이니셜이라고 한다. 모든 윈도우의 실행파일은 MZ로 시작하기 때문에 이 값을 이용해  
                   실행파일을 찾을 수도 있다. 참고로 오프셋은 0x00 ~ 0x01
- e_lfanew : 이 구조체 멤버는 PE 파일의 머리 격인 IMAGE_NT_HEADER를 가리키는 오프셋 값을 가지고 있다.
                  참고로 오프셋은 0x3C ~ 0x3F

아래 이미지는 notepad.exe의 DOS MZ HEADER 영역을 보여준다.

[그림 2 - DOS MZ HEADER 영역]

이 두값만 올바르다면, 프로그램은 실행하는데 문제가 없다.


[DOS Stub Program]
이 부분은 사용자가 DOS 모드에서 윈도우용 실행파일을 실행 했을시 아래와 같은 문구를 출력해주기 위한 코드가 있는 부분이다.

"This Program connot be run is DOS mode" 

이 부분은 오프셋 0x40 ~ 0x7F 까지 이다.

[그림 3 - DOS Stub Program 부분]


'[+] Information > [-] RCE' 카테고리의 다른 글

PE 구조 (4)  (0) 2011.12.30
PE 구조 (3)  (0) 2011.12.30
PE 구조 (2)  (0) 2011.12.29
PE 구조 (1)  (0) 2011.12.29
Lena's Tutorial 11 상세 분석  (0) 2011.10.13

+ Recent posts