반응형
#include "header.h"

void print_inh_ioh_datadirectory(FILE* fp, unsigned char* buf, operand operand_type)
{
    IMAGE_DOS_HEADER* idh = (IMAGE_DOS_HEADER*)buf;

    switch (operand_type)
    {
        case OPERAND_NT32_DATADIRECTORY:
        {
            char* inh32_datadirectory_entries[] = { "EXPORT", "IMPORT", "RESOURCE", "EXCEPTION", "SECURITY", "BASERELOC", "DEBUG\t", "COPYRIGHT", "GLOBALPTR", "TLS\t", "LOAD_CONFIG", "BOUND_IMPORT", "IAT\t", "DELAY_IMPORT", "COM_DESCRIPTOR", "Reserved" };

            IMAGE_NT_HEADERS32* inh32 = (IMAGE_NT_HEADERS32*)(buf + idh->e_lfanew);

            for (int i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++)
            {
                printf("[%08X] - %s Directory RVA[%zdbyte]\t: %08X\n", offset, inh32_datadirectory_entries[i], sizeof(inh32->OptionalHeader.DataDirectory[i].VirtualAddress), inh32->OptionalHeader.DataDirectory[i].VirtualAddress);
                offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.DataDirectory[i].VirtualAddress));
                
                printf("[%08X] - %s Directory Size[%zdbyte]\t: %08X\n", offset, inh32_datadirectory_entries[i], sizeof(inh32->OptionalHeader.DataDirectory[i].Size), inh32->OptionalHeader.DataDirectory[i].Size);
                offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.DataDirectory[i].Size));
            }
            break;
        }
        case OPERAND_NT64_DATADIRECTORY:
        {
            char* inh64_datadirectory_entries[] = { "EXPORT", "IMPORT", "RESOURCE", "EXCEPTION", "SECURITY", "BASERELOC", "DEBUG\t", "ARCHITECTURE", "GLOBALPTR", "TLS\t", "LOAD_CONFIG", "BOUND_IMPORT", "IAT\t", "DELAY_IMPORT", "COM_DESCRIPTOR", "Reserved" };

            IMAGE_NT_HEADERS64* inh64 = (IMAGE_NT_HEADERS64*)(buf + idh->e_lfanew);

            for (int i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++)
            {
                printf("[%08X] - %s Directory RVA[%zdbyte]\t: %08X\n", offset, inh64_datadirectory_entries[i], sizeof(inh64->OptionalHeader.DataDirectory[i].VirtualAddress), inh64->OptionalHeader.DataDirectory[i].VirtualAddress);
                offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.DataDirectory[i].VirtualAddress));
                
                printf("[%08X] - %s Directory Size[%zdbyte]\t: %08X\n", offset, inh64_datadirectory_entries[i], sizeof(inh64->OptionalHeader.DataDirectory[i].Size), inh64->OptionalHeader.DataDirectory[i].Size);
                offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.DataDirectory[i].Size));
            }
            break;
        }
    }
}


매개변수

void print_inh_ioh_datadirectory(FILE* fp, unsigned char* buf, operand operand_type)

인자로 파일 포인터, 파일의 내용이 담긴 동적 메모리의 주소, operand형의 operand 타입을 받는다.

 

fp : 파일 오프셋을 출력하기 위함이다.

 

buf : NT header의 Optional header의 내용 중 DataDirectory 부분을 출력하기 때문에 바로 IMAGE_NT_HEADER 구조체 정보를 받아도 되지만, 함수 내에서 offset 계산과 32bit, 64bit에 따라 사용해야 하는 구조체가 다르므로 buf 전체를 받아 32bit와 64bit 각각에 맞는 구조체를 선언하게끔 하기 위함이다.

 

typedef enum
{
    OPERAND_DWORD,
    OPERAND_ULONGLONG,
    OPERAND_NT32,
    OPERAND_NT64,
    OPERAND_NT32_DATADIRECTORY,
    OPERAND_NT64_DATADIRECTORY,
    OPERAND_IID32,
    OPERAND_IID64
} operand;

 

operand_type : 위의 익명 enum 구조체로 정의된 값 중 nt32_datadirectory인지 nt64_datadirectory인지 검사하여 값에 맞는 파싱 작업을 해 출력하도록 하기 위함이다.


32bit 64bit로 나눈 이유

 

32bit와 64bit에 따라 NT header 구조체 32 혹은 64버전을 써야 하기 때문이고

 

char* inh32_datadirectory_entries[] = { "EXPORT", "IMPORT", "RESOURCE", "EXCEPTION", "SECURITY", "BASERELOC", "DEBUG\t", "COPYRIGHT", "GLOBALPTR", "TLS\t", "LOAD_CONFIG", "BOUND_IMPORT", "IAT\t", "DELAY_IMPORT", "COM_DESCRIPTOR", "Reserved" };
char* inh64_datadirectory_entries[] = { "EXPORT", "IMPORT", "RESOURCE", "EXCEPTION", "SECURITY", "BASERELOC", "DEBUG\t", "ARCHITECTURE", "GLOBALPTR", "TLS\t", "LOAD_CONFIG", "BOUND_IMPORT", "IAT\t", "DELAY_IMPORT", "COM_DESCRIPTOR", "Reserved" };

 

IMAGE_OPTIONAL_HEADER32에서의 엔트리 이름과 IMAGE_OPTIONAL_HEADER64에서의 엔트리 이름이 비슷하지만 한 개가 다르기 때문이다.


출력 코드

for (int i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++)
{
    printf("[%08X] - %s Directory RVA[%zdbyte]\t: %08X\n", offset, inh32_datadirectory_entries[i], sizeof(inh32->OptionalHeader.DataDirectory[i].VirtualAddress), inh32->OptionalHeader.DataDirectory[i].VirtualAddress);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.DataDirectory[i].VirtualAddress));
    
    printf("[%08X] - %s Directory Size[%zdbyte]\t: %08X\n", offset, inh32_datadirectory_entries[i], sizeof(inh32->OptionalHeader.DataDirectory[i].Size), inh32->OptionalHeader.DataDirectory[i].Size);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.DataDirectory[i].Size));
}

 

for문으로 엔트리의 값(RVA)과 Size 값을 출력하고 출력한 값만큼 파일 오프셋을 이동시킨다.

 

 

반응형

+ Recent posts