반응형
#include "header.h"

void print_section_header(FILE* fp, IMAGE_SECTION_HEADER* ish, WORD section_num)
{
	printf("========== [SECTION HEADERS] ==========\n\n");
	printf("Number of Section : %d\n\n", section_num);
	for (int i = 0; i < section_num; i++, ish++)
	{
		printf("[%08X] - Section Name\t\t: %s\n", offset, ish->Name);
		offset = get_file_offset(fp, sizeof(ish->Name));

		//printf("- PhysicalAddress[%dbyte]\t:%08X\n", sizeof(ish->Misc.PhysicalAddress), ish->Misc.PhysicalAddress);
		printf("[%08X] - VirtualSize[%zdbyte]\t\t: %08X\n", offset, sizeof(ish->Misc.VirtualSize), ish->Misc.VirtualSize);
		offset = get_file_offset(fp, sizeof(ish->Misc.VirtualSize));

		printf("[%08X] - VirtualAddress[%zdbyte]\t: %08X\n", offset, sizeof(ish->VirtualAddress), ish->VirtualAddress);
		offset = get_file_offset(fp, sizeof(ish->VirtualAddress));

		printf("[%08X] - SizeOfRawData[%zdbyte]\t: %08X\n", offset, sizeof(ish->SizeOfRawData), ish->SizeOfRawData);
		offset = get_file_offset(fp, sizeof(ish->SizeOfRawData));

		printf("[%08X] - PointerToRawData[%zdbyte]\t: %08X\n", offset, sizeof(ish->PointerToRawData), ish->PointerToRawData);
		offset = get_file_offset(fp, sizeof(ish->PointerToRawData));

		printf("[%08X] - PointerToRelocations[%zdbyte]: %08X\n", offset, sizeof(ish->PointerToRelocations), ish->PointerToRelocations);
		offset = get_file_offset(fp, sizeof(ish->PointerToRelocations));

		printf("[%08X] - PointerToLinenumbers[%zdbyte]: %08X\n", offset, sizeof(ish->PointerToLinenumbers), ish->PointerToLinenumbers);
		offset = get_file_offset(fp, sizeof(ish->PointerToLinenumbers));

		printf("[%08X] - NumberOfRelocations[%zdbyte]\t: %04X\n", offset, sizeof(ish->NumberOfRelocations), ish->NumberOfRelocations);
		offset = get_file_offset(fp, sizeof(ish->NumberOfRelocations));

		printf("[%08X] - NumberOfLineNumbers[%zdbyte]\t: %04X\n", offset, sizeof(ish->NumberOfLinenumbers), ish->NumberOfLinenumbers);
		offset = get_file_offset(fp, sizeof(ish->NumberOfLinenumbers));

		printf("[%08X] - Characteristics[%zdbyte]\t: %08X\n\n", offset, sizeof(ish->Characteristics), ish->Characteristics);
		offset = get_file_offset(fp, sizeof(ish->Characteristics));

		printf("----------------------------------------\n\n");
	}
	printf("=======================================\n\n");
}

 


매개변수

void print_section_header(FILE* fp, IMAGE_SECTION_HEADER* ish, WORD section_num)

인자로 파일 포인터와 section header 구조체 정보 그리고 section 개수를 받는다.

 

fp는 offset도 같이 출력해주기 위함이고, section_num은 섹션의 개수만큼 for문으로 출력하기 위함이다.

 


IMAGE_SECTION_HEADER 구조체 정의

#define IMAGE_SIZEOF_SHORT_NAME 	8

typedef struct _IMAGE_SECTION_HEADER {
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
    union {
        DWORD   PhysicalAddress;
        DWORD   VirtualSize;
    } Misc;
    DWORD   VirtualAddress;
    DWORD   SizeOfRawData;
    DWORD   PointerToRawData;
    DWORD   PointerToRelocations;
    DWORD   PointerToLinenumbers;
    WORD    NumberOfRelocations;
    WORD    NumberOfLinenumbers;
    DWORD   Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

 

IMAGE_SECTION_HEADER 구조체는 winnt.h 헤더 파일에 위와 같이 되어 있다.

 


주요 구조체 멤버

  • VirtualSize : 메모리에서 섹션이 차지하는 크기
  • VirtualAddress : 메모리에서 섹션의 시작 주소(RVA)
  • SizeOfRawData : 파일에서 섹션이 차지하는 크기
  • PointerToRawData : 파일에서 섹션의 시작 위치
  • Characteristics : 섹션의 속성(bit OR)

 

VirtualAddress와 PointerToRawData는 아무 값이나 가질 수 없고, 각각 IMAGE_OPTIONAL_HEADER32에 정의된 SectionAlignment와 FileAlignment에 맞게 결정된다.

 

VirtualSize와 SizeOfRawData는 일반적으로 서로 다른 값을 가지는데 즉, 파일에서의 섹션 크기와 메모리에 로딩된 섹션의 크기는 다르다.

 

VirtualAddress와 VirtualSize는 이후에 RVA 값을 RAW 값으로 변환하는 계산에 이용되는 항목이다.

 

Characteristics는 아래에 표시된 값을의 조합(bit OR)으로 이루어진다.

#define IMAGE_SCN_CNT_CODE                   0x00000020  // Section contains code.
#define IMAGE_SCN_CNT_INITIALIZED_DATA       0x00000040  // Section contains initialized data.
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA     0x00000080  // Section contains uninitialized data.
#define IMAGE_SCN_MEM_EXECUTE                0x20000000  // Section is executable.
#define IMAGE_SCN_MEM_READ                   0x40000000  // Section is readable.
#define IMAGE_SCN_MEM_WRITE                  0x80000000  // Section is writeable.

 

마지막으로 Name 멤버는 C 언어의 문자열처럼 NULL로 끝나지 않고, 또한 ASCII 값만 와야 한다는 제한도 없다.

 

PE 스펙에는 섹션 Name에 대한 어떠한 명시적인 규칙이 없기 때문에 어떠한 값을 넣어도 되고 심지어는 NULL로 채워도 된다.

 

그렇기에 섹션의 Name은 그냥 참고용일 뿐 어떤 정보로써 활용하기에는 장담할 수 없다.

(데이터 세션 이름을 ‘.code’라고 해도 된다.)


출력 코드

printf("========== [SECTION HEADERS] ==========\n\n");
printf("Number of Section : %d\n\n", section_num);
for (int i = 0; i < section_num; i++, ish++)
{
    printf("[%08X] - Section Name\t\t: %s\n", offset, ish->Name);
    offset = get_file_offset(fp, sizeof(ish->Name));

    //printf("- PhysicalAddress[%dbyte]\t:%08X\n", sizeof(ish->Misc.PhysicalAddress), ish->Misc.PhysicalAddress);
    printf("[%08X] - VirtualSize[%zdbyte]\t\t: %08X\n", offset, sizeof(ish->Misc.VirtualSize), ish->Misc.VirtualSize);
    offset = get_file_offset(fp, sizeof(ish->Misc.VirtualSize));

    printf("[%08X] - VirtualAddress[%zdbyte]\t: %08X\n", offset, sizeof(ish->VirtualAddress), ish->VirtualAddress);
    offset = get_file_offset(fp, sizeof(ish->VirtualAddress));

    printf("[%08X] - SizeOfRawData[%zdbyte]\t: %08X\n", offset, sizeof(ish->SizeOfRawData), ish->SizeOfRawData);
    offset = get_file_offset(fp, sizeof(ish->SizeOfRawData));

    printf("[%08X] - PointerToRawData[%zdbyte]\t: %08X\n", offset, sizeof(ish->PointerToRawData), ish->PointerToRawData);
    offset = get_file_offset(fp, sizeof(ish->PointerToRawData));

    printf("[%08X] - PointerToRelocations[%zdbyte]: %08X\n", offset, sizeof(ish->PointerToRelocations), ish->PointerToRelocations);
    offset = get_file_offset(fp, sizeof(ish->PointerToRelocations));

    printf("[%08X] - PointerToLinenumbers[%zdbyte]: %08X\n", offset, sizeof(ish->PointerToLinenumbers), ish->PointerToLinenumbers);
    offset = get_file_offset(fp, sizeof(ish->PointerToLinenumbers));

    printf("[%08X] - NumberOfRelocations[%zdbyte]\t: %04X\n", offset, sizeof(ish->NumberOfRelocations), ish->NumberOfRelocations);
    offset = get_file_offset(fp, sizeof(ish->NumberOfRelocations));

    printf("[%08X] - NumberOfLineNumbers[%zdbyte]\t: %04X\n", offset, sizeof(ish->NumberOfLinenumbers), ish->NumberOfLinenumbers);
    offset = get_file_offset(fp, sizeof(ish->NumberOfLinenumbers));

    printf("[%08X] - Characteristics[%zdbyte]\t: %08X\n\n", offset, sizeof(ish->Characteristics), ish->Characteristics);
    offset = get_file_offset(fp, sizeof(ish->Characteristics));

    printf("----------------------------------------\n\n");
}
printf("=======================================\n\n");

 

섹션의 총 개수를 출력해주고, 섹션의 총 개수만큼 for문으로 반복적으로 한 섹션에 대한 각 멤버들의 값을 출력한다.

 

출력한 멤버의 크기만큼 파일 오프셋을 이동시켜 파일 오프셋 값도 출력한다.

반응형

+ Recent posts