반응형
#include "header.h"

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

    switch (operand_type)
    {
        case OPERAND_NT32:
        {
            IMAGE_NT_HEADERS32* inh32 = (IMAGE_NT_HEADERS32*)(buf + idh->e_lfanew);

            // 파일 포인터를 NT header 위치로 이동
            offset = set_file_offset(fp, idh->e_lfanew);

            printf("=============== [NT Header 32] ===============\n\n");
            printf("[%08X] - Signature[%zdbyte]\t\t\t: %08X\n\n", offset, sizeof(inh32->Signature), inh32->Signature);
            offset = get_file_offset(fp, sizeof(inh32->Signature));

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

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

            printf("[%08X] - TimeDateStamp[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->FileHeader.TimeDateStamp), inh32->FileHeader.TimeDateStamp);
            offset = get_file_offset(fp, sizeof(inh32->FileHeader.TimeDateStamp));

            printf("[%08X] - PointerToSymbolTable[%zdbyte]\t: %08X\n", offset, sizeof(inh32->FileHeader.PointerToSymbolTable), inh32->FileHeader.PointerToSymbolTable);
            offset = get_file_offset(fp, sizeof(inh32->FileHeader.PointerToSymbolTable));

            printf("[%08X] - NumberOfSymbols[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->FileHeader.NumberOfSymbols), inh32->FileHeader.NumberOfSymbols);
            offset = get_file_offset(fp, sizeof(inh32->FileHeader.NumberOfSymbols));

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

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

            printf("--------------- (OptionalHeader 32) ---------------\n");
            printf("[%08X] - Magic[%zdbyte]\t\t\t: %04X\n", offset, sizeof(inh32->OptionalHeader.Magic), inh32->OptionalHeader.Magic);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.Magic));

            printf("[%08X] - MajorLinkerVersion[%zdbyte]\t\t: %02X\n", offset, sizeof(inh32->OptionalHeader.MajorLinkerVersion), inh32->OptionalHeader.MajorLinkerVersion);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.MajorLinkerVersion));

            printf("[%08X] - MinorLinkerVersion[%zdbyte]\t\t: %02X\n", offset, sizeof(inh32->OptionalHeader.MinorLinkerVersion), inh32->OptionalHeader.MinorLinkerVersion);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.MinorLinkerVersion));

            printf("[%08X] - SizeofCode[%zdbyte]\t\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.SizeOfCode), inh32->OptionalHeader.SizeOfCode);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.SizeOfCode));

            printf("[%08X] - SizeofInitializedData[%zdbyte]\t: %08X\n", offset, sizeof(inh32->OptionalHeader.SizeOfInitializedData), inh32->OptionalHeader.SizeOfInitializedData);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.SizeOfInitializedData));

            printf("[%08X] - SizeOfUninitializedData[%zdbyte]\t: %08X\n", offset, sizeof(inh32->OptionalHeader.SizeOfUninitializedData), inh32->OptionalHeader.SizeOfUninitializedData);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.SizeOfUninitializedData));

            printf("[%08X] - AddressOfEntryPoint[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.AddressOfEntryPoint), inh32->OptionalHeader.AddressOfEntryPoint);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.AddressOfEntryPoint));

            printf("[%08X] - BaseOfCode[%zdbyte]\t\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.BaseOfCode), inh32->OptionalHeader.BaseOfCode);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.BaseOfCode));

            printf("[%08X] - BaseOfData[%zdbyte]\t\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.BaseOfData), inh32->OptionalHeader.BaseOfData);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.BaseOfData));

            printf("[%08X] - ImageBase[%zdbyte]\t\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.ImageBase), inh32->OptionalHeader.ImageBase);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.ImageBase));

            printf("[%08X] - SectionAlignment[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.SectionAlignment), inh32->OptionalHeader.SectionAlignment);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.SectionAlignment));

            printf("[%08X] - FileAlignment[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.FileAlignment), inh32->OptionalHeader.FileAlignment);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.FileAlignment));

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

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

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

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

            printf("[%08X] - MajorSubsystemVersion[%zdbyte]\t: %04X\n", offset, sizeof(inh32->OptionalHeader.MajorSubsystemVersion), inh32->OptionalHeader.MajorSubsystemVersion);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.MajorOperatingSystemVersion));

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

            printf("[%08X] - Win32VersionValue[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.Win32VersionValue), inh32->OptionalHeader.Win32VersionValue);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.Win32VersionValue));

            printf("[%08X] - SizeOfImage[%zdbyte]\t\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.SizeOfImage), inh32->OptionalHeader.SizeOfImage);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.SizeOfImage));

            printf("[%08X] - SizeOfHeaders[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.SizeOfHeaders), inh32->OptionalHeader.SizeOfHeaders);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.SizeOfHeaders));

            printf("[%08X] - CheckSum[%zdbyte]\t\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.CheckSum), inh32->OptionalHeader.CheckSum);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.CheckSum));

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

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

            printf("[%08X] - SizeOfStackReserve[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.SizeOfStackReserve), inh32->OptionalHeader.SizeOfStackReserve);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.SizeOfStackReserve));

            printf("[%08X] - SizeOfStackCommit[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.SizeOfStackCommit), inh32->OptionalHeader.SizeOfStackCommit);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.SizeOfStackCommit));

            printf("[%08X] - SizeOfHeapReserve[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.SizeOfHeapReserve), inh32->OptionalHeader.SizeOfHeapReserve);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.SizeOfHeapReserve));

            printf("[%08X] - SizeOfHeapCommit[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.SizeOfHeapCommit), inh32->OptionalHeader.SizeOfHeapCommit);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.SizeOfHeapCommit));

            printf("[%08X] - LoaderFlags[%zdbyte]\t\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.LoaderFlags), inh32->OptionalHeader.LoaderFlags);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.LoaderFlags));

            printf("[%08X] - NumberOfRvaAndSizes[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.NumberOfRvaAndSizes), inh32->OptionalHeader.NumberOfRvaAndSizes);
            offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.NumberOfRvaAndSizes));

            /*for (int i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++)
            {
                printf("- DataDirectory[%d].VirtualAddress[%dbyte]\t:%08X\n", i, sizeof(inh32->OptionalHeader.DataDirectory[i].VirtualAddress), inh32->OptionalHeader.DataDirectory[i].VirtualAddress);
                printf("- DataDirectory[%d].Size[%dbyte]\t\t\t:%08X\n", i, sizeof(inh32->OptionalHeader.DataDirectory[i].Size), inh32->OptionalHeader.DataDirectory[i].Size);
            }
            */

            print_inh_ioh_datadirectory(fp, buf, OPERAND_NT32_DATADIRECTORY);

            printf("--------------------------------------------------\n\n");
            printf("==================================================\n\n");
            break;
        }
        case OPERAND_NT64:
        {
            IMAGE_NT_HEADERS64* inh64 = (IMAGE_NT_HEADERS64*)(buf + idh->e_lfanew);

            // 파일 포인터를 NT header 위치로 이동
            offset = set_file_offset(fp, idh->e_lfanew);

            printf("=============== [NT Header 64] ===============\n\n");
            printf("[%08X] - Signature[%zdbyte]\t\t\t: %08X\n\n", offset, sizeof(inh64->Signature), inh64->Signature);
            offset = get_file_offset(fp, sizeof(inh64->Signature));

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

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

            printf("[%08X] - TimeDateStamp[%zdbyte]\t\t: %08X\n", offset, sizeof(inh64->FileHeader.TimeDateStamp), inh64->FileHeader.TimeDateStamp);
            offset = get_file_offset(fp, sizeof(inh64->FileHeader.TimeDateStamp));

            printf("[%08X] - PointerToSymbolTable[%zdbyte]\t: %08X\n", offset, sizeof(inh64->FileHeader.PointerToSymbolTable), inh64->FileHeader.PointerToSymbolTable);
            offset = get_file_offset(fp, sizeof(inh64->FileHeader.PointerToSymbolTable));

            printf("[%08X] - NumberOfSymbols[%zdbyte]\t\t: %08X\n", offset, sizeof(inh64->FileHeader.NumberOfSymbols), inh64->FileHeader.NumberOfSymbols);
            offset = get_file_offset(fp, sizeof(inh64->FileHeader.NumberOfSymbols));

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

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

            printf("--------------- (OptionalHeader 64) ---------------\n");
            printf("[%08X] - Magic[%zdbyte]\t\t\t: %04X\n", offset, sizeof(inh64->OptionalHeader.Magic), inh64->OptionalHeader.Magic);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.Magic));

            printf("[%08X] - MajorLinkerVersion[%zdbyte]\t\t: %02X\n", offset, sizeof(inh64->OptionalHeader.MajorLinkerVersion), inh64->OptionalHeader.MajorLinkerVersion);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.MajorLinkerVersion));

            printf("[%08X] - MinorLinkerVersion[%zdbyte]\t\t: %02X\n", offset, sizeof(inh64->OptionalHeader.MinorLinkerVersion), inh64->OptionalHeader.MinorLinkerVersion);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.MinorLinkerVersion));

            printf("[%08X] - SizeofCode[%zdbyte]\t\t\t: %08X\n", offset, sizeof(inh64->OptionalHeader.SizeOfCode), inh64->OptionalHeader.SizeOfCode);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.SizeOfCode));

            printf("[%08X] - SizeofInitializedData[%zdbyte]\t: %08X\n", offset, sizeof(inh64->OptionalHeader.SizeOfInitializedData), inh64->OptionalHeader.SizeOfInitializedData);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.SizeOfInitializedData));

            printf("[%08X] - SizeOfUninitializedData[%zdbyte]\t: %08X\n", offset, sizeof(inh64->OptionalHeader.SizeOfUninitializedData), inh64->OptionalHeader.SizeOfUninitializedData);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.SizeOfUninitializedData));

            printf("[%08X] - AddressOfEntryPoint[%zdbyte]\t\t: %08X\n", offset, sizeof(inh64->OptionalHeader.AddressOfEntryPoint), inh64->OptionalHeader.AddressOfEntryPoint);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.AddressOfEntryPoint));

            printf("[%08X] - BaseOfCode[%zdbyte]\t\t\t: %08X\n", offset, sizeof(inh64->OptionalHeader.BaseOfCode), inh64->OptionalHeader.BaseOfCode);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.BaseOfCode));


            printf("[%08X] - ImageBase[%zdbyte]\t\t\t: %016llX\n", offset, sizeof(inh64->OptionalHeader.ImageBase), inh64->OptionalHeader.ImageBase);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.ImageBase));

            printf("[%08X] - SectionAlignment[%zdbyte]\t\t: %08X\n", offset, sizeof(inh64->OptionalHeader.SectionAlignment), inh64->OptionalHeader.SectionAlignment);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.SectionAlignment));

            printf("[%08X] - FileAlignment[%zdbyte]\t\t: %08X\n", offset, sizeof(inh64->OptionalHeader.FileAlignment), inh64->OptionalHeader.FileAlignment);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.FileAlignment));

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

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

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

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

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

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

            printf("[%08X] - Win32VersionValue[%zdbyte]\t\t: %08X\n", offset, sizeof(inh64->OptionalHeader.Win32VersionValue), inh64->OptionalHeader.Win32VersionValue);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.Win32VersionValue));

            printf("[%08X] - SizeOfImage[%zdbyte]\t\t\t: %08X\n", offset, sizeof(inh64->OptionalHeader.SizeOfImage), inh64->OptionalHeader.SizeOfImage);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.SizeOfImage));

            printf("[%08X] - SizeOfHeaders[%zdbyte]\t\t: %08X\n", offset, sizeof(inh64->OptionalHeader.SizeOfHeaders), inh64->OptionalHeader.SizeOfHeaders);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.SizeOfHeaders));

            printf("[%08X] - CheckSum[%zd]\t\t\t: %08X\n", offset, sizeof(inh64->OptionalHeader.CheckSum), inh64->OptionalHeader.CheckSum);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.CheckSum));

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

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

            printf("[%08X] - SizeOfStackReserve[%zdbyte]\t\t: %016llX\n", offset, sizeof(inh64->OptionalHeader.SizeOfStackReserve), inh64->OptionalHeader.SizeOfStackReserve);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.SizeOfStackReserve));

            printf("[%08X] - SizeOfStackCommit[%zdbyte]\t\t: %016llX\n", offset, sizeof(inh64->OptionalHeader.SizeOfStackCommit), inh64->OptionalHeader.SizeOfStackCommit);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.SizeOfStackCommit));

            printf("[%08X] - SizeOfHeapReserve[%zdbyte]\t\t: %016llX\n", offset, sizeof(inh64->OptionalHeader.SizeOfHeapReserve), inh64->OptionalHeader.SizeOfHeapReserve);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.SizeOfHeapReserve));

            printf("[%08X] - SizeOfHeapCommit[%zdbyte]\t\t: %016llX\n", offset, sizeof(inh64->OptionalHeader.SizeOfHeapCommit), inh64->OptionalHeader.SizeOfHeapCommit);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.SizeOfHeapCommit));

            printf("[%08X] - LoaderFlags[%zdbyte]\t\t\t: %08X\n", offset, sizeof(inh64->OptionalHeader.LoaderFlags), inh64->OptionalHeader.LoaderFlags);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.LoaderFlags));

            printf("[%08X] - NumberOfRvaAndSizes[%zdbyte]\t\t: %08X\n", offset, sizeof(inh64->OptionalHeader.NumberOfRvaAndSizes), inh64->OptionalHeader.NumberOfRvaAndSizes);
            offset = get_file_offset(fp, sizeof(inh64->OptionalHeader.NumberOfRvaAndSizes));

            /*
            for (int i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++)
            {
                printf("- DataDirectory[%d].VirtualAddress[%dbyte]\t:%08X\n", i, sizeof(inh64->OptionalHeader.DataDirectory[i].VirtualAddress), inh64->OptionalHeader.DataDirectory[i].VirtualAddress);
                printf("- DataDirectory[%d].Size[%dbyte]\t\t\t:%08X\n", i, sizeof(inh64->OptionalHeader.DataDirectory[i].Size), inh64->OptionalHeader.DataDirectory[i].Size);
            }
            */

            print_inh_ioh_datadirectory(fp, buf, OPERAND_NT64_DATADIRECTORY);

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


매개변수

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

 

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

 

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

 

buf : print_nt_header이기 때문에 IMAGE_NT_HEADER를 바로 받으면 되지만, 32bit인지 64bit인지에 따라 NT header 내의 Optional header 구조체가 달라지기도 하고, print_nt_header() 함수가 독립적으로 사용되더라도 동작되도록 하기 위해 파일 내용이 담긴 동적 메모리의 주소를 받아 NT header 위치로 찾아가기 위함이다.

 

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인지 nt64인지 검사하여 값에 맞는 파싱 작업을 해 출력하도록 하기 위함이다.

 


IMAGE_NT_HEADER 구조체 정의

 

typedef struct _IMAGE_NT_HEADERS64 {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER64 OptionalHeader;
} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;

typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

 

winnt.h 헤더 파일을 보면 위와 같이 나와있다.

 

IMAGE_NT_HEADERS32와 IMAGE_NT_HEADERS64 모두 IMAGE_FILE_HEADER 구조체는 같은 것을 쓰지만, IMAGE_OPTIONAL HEADER는 32와 64로 나뉘어져 있다.

 

typedef struct _IMAGE_OPTIONAL_HEADER {
    //
    // Standard fields.
    //

    WORD    Magic;
    BYTE    MajorLinkerVersion;
    BYTE    MinorLinkerVersion;
    DWORD   SizeOfCode;
    DWORD   SizeOfInitializedData;
    DWORD   SizeOfUninitializedData;
    DWORD   AddressOfEntryPoint;
    DWORD   BaseOfCode;
    DWORD   BaseOfData;

    //
    // NT additional fields.
    //

    DWORD   ImageBase;
    DWORD   SectionAlignment;
    DWORD   FileAlignment;
    WORD    MajorOperatingSystemVersion;
    WORD    MinorOperatingSystemVersion;
    WORD    MajorImageVersion;
    WORD    MinorImageVersion;
    WORD    MajorSubsystemVersion;
    WORD    MinorSubsystemVersion;
    DWORD   Win32VersionValue;
    DWORD   SizeOfImage;
    DWORD   SizeOfHeaders;
    DWORD   CheckSum;
    WORD    Subsystem;
    WORD    DllCharacteristics;
    DWORD   SizeOfStackReserve;
    DWORD   SizeOfStackCommit;
    DWORD   SizeOfHeapReserve;
    DWORD   SizeOfHeapCommit;
    DWORD   LoaderFlags;
    DWORD   NumberOfRvaAndSizes;
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

 

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

 

typedef struct _IMAGE_OPTIONAL_HEADER64 {
    WORD        Magic;
    BYTE        MajorLinkerVersion;
    BYTE        MinorLinkerVersion;
    DWORD       SizeOfCode;
    DWORD       SizeOfInitializedData;
    DWORD       SizeOfUninitializedData;
    DWORD       AddressOfEntryPoint;
    DWORD       BaseOfCode;
    ULONGLONG   ImageBase;
    DWORD       SectionAlignment;
    DWORD       FileAlignment;
    WORD        MajorOperatingSystemVersion;
    WORD        MinorOperatingSystemVersion;
    WORD        MajorImageVersion;
    WORD        MinorImageVersion;
    WORD        MajorSubsystemVersion;
    WORD        MinorSubsystemVersion;
    DWORD       Win32VersionValue;
    DWORD       SizeOfImage;
    DWORD       SizeOfHeaders;
    DWORD       CheckSum;
    WORD        Subsystem;
    WORD        DllCharacteristics;
    ULONGLONG   SizeOfStackReserve;
    ULONGLONG   SizeOfStackCommit;
    ULONGLONG   SizeOfHeapReserve;
    ULONGLONG   SizeOfHeapCommit;
    DWORD       LoaderFlags;
    DWORD       NumberOfRvaAndSizes;
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;

 

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

 


주요 구조체 멤버

 

NT header

  • Signature : PE 파일의 시그니처 값이 들어있는 멤버이다.

 

File header

  • Machine : CPU 별로 고유한 값
// https://codemachine.com/downloads/win80/winnt.h
#define IMAGE_FILE_MACHINE_UNKNOWN           0
#define IMAGE_FILE_MACHINE_I386              0x014c  // Intel 386.
#define IMAGE_FILE_MACHINE_R3000             0x0162  // MIPS little-endian, 0x160 big-endian
#define IMAGE_FILE_MACHINE_R4000             0x0166  // MIPS little-endian
#define IMAGE_FILE_MACHINE_R10000            0x0168  // MIPS little-endian
#define IMAGE_FILE_MACHINE_WCEMIPSV2         0x0169  // MIPS little-endian WCE v2
#define IMAGE_FILE_MACHINE_ALPHA             0x0184  // Alpha_AXP
#define IMAGE_FILE_MACHINE_SH3               0x01a2  // SH3 little-endian
#define IMAGE_FILE_MACHINE_SH3DSP            0x01a3
#define IMAGE_FILE_MACHINE_SH3E              0x01a4  // SH3E little-endian
#define IMAGE_FILE_MACHINE_SH4               0x01a6  // SH4 little-endian
#define IMAGE_FILE_MACHINE_SH5               0x01a8  // SH5
#define IMAGE_FILE_MACHINE_ARM               0x01c0  // ARM Little-Endian
#define IMAGE_FILE_MACHINE_THUMB             0x01c2  // ARM Thumb/Thumb-2 Little-Endian
#define IMAGE_FILE_MACHINE_ARMNT             0x01c4  // ARM Thumb-2 Little-Endian
#define IMAGE_FILE_MACHINE_AM33              0x01d3
#define IMAGE_FILE_MACHINE_POWERPC           0x01F0  // IBM PowerPC Little-Endian
#define IMAGE_FILE_MACHINE_POWERPCFP         0x01f1
#define IMAGE_FILE_MACHINE_IA64              0x0200  // Intel 64
#define IMAGE_FILE_MACHINE_MIPS16            0x0266  // MIPS
#define IMAGE_FILE_MACHINE_ALPHA64           0x0284  // ALPHA64
#define IMAGE_FILE_MACHINE_MIPSFPU           0x0366  // MIPS
#define IMAGE_FILE_MACHINE_MIPSFPU16         0x0466  // MIPS
#define IMAGE_FILE_MACHINE_AXP64             IMAGE_FILE_MACHINE_ALPHA64
#define IMAGE_FILE_MACHINE_TRICORE           0x0520  // Infineon
#define IMAGE_FILE_MACHINE_CEF               0x0CEF
#define IMAGE_FILE_MACHINE_EBC               0x0EBC  // EFI Byte Code
#define IMAGE_FILE_MACHINE_AMD64             0x8664  // AMD64 (K8)
#define IMAGE_FILE_MACHINE_M32R              0x9041  // M32R little-endian
#define IMAGE_FILE_MACHINE_CEE               0xC0EE
  • NumberOfSections : 섹션의 개수를 나타낸다. (반드시 0보다 커야 하고, 정의된 섹션 개수와 실제 섹션이 다르면 실행 에러가 발생)
  • SizeOfOptionalHeader : OptionalHeader의 크기(패커들은 이 멤버의 값을 수정할 수도 있다.)
  • Characteristics : 파일의 속성을 나타내는 값으로, 실행이 가능한 형태인지(Executable or not) 혹은 DLL 파일인지 등의 정보들이 bit OR 형식으로 조합
#define IMAGE_FILE_RELOCS_STRIPPED           0x0001  // Relocation info stripped from file.
#define IMAGE_FILE_EXECUTABLE_IMAGE          0x0002  // File is executable  (i.e. no unresolved externel references).
#define IMAGE_FILE_LINE_NUMS_STRIPPED        0x0004  // Line nunbers stripped from file.
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED       0x0008  // Local symbols stripped from file.
#define IMAGE_FILE_AGGRESIVE_WS_TRIM         0x0010  // Agressively trim working set
#define IMAGE_FILE_LARGE_ADDRESS_AWARE       0x0020  // App can handle >2gb addresses
#define IMAGE_FILE_BYTES_REVERSED_LO         0x0080  // Bytes of machine word are reversed.
#define IMAGE_FILE_32BIT_MACHINE             0x0100  // 32 bit word machine.
#define IMAGE_FILE_DEBUG_STRIPPED            0x0200  // Debugging info stripped from file in .DBG file
#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP   0x0400  // If Image is on removable media, copy and run from the swap file.
#define IMAGE_FILE_NET_RUN_FROM_SWAP         0x0800  // If Image is on Net, copy and run from the swap file.
#define IMAGE_FILE_SYSTEM                    0x1000  // System File.
#define IMAGE_FILE_DLL                       0x2000  // File is a DLL.
#define IMAGE_FILE_UP_SYSTEM_ONLY            0x4000  // File should only be run on a UP machine
#define IMAGE_FILE_BYTES_REVERSED_HI         0x8000  // Bytes of machine word are reversed.

 

Optional header

  • Magic : IMAGE_OPTIONAL_HEADER32 구조체인 경우 10B, IMAGE_OPTIONAL_HEADER64 구조체인 경우 20B 값
  • AddressOfEntryPoint : EntryPoint의 RVA 값(이 값은 프로그램에서 최초로 실행되는 코드의 시작 주소로 매우 중요한 값이다.)
  • ImageBase : PE 로더는 PE 파일을 실행시키기 위해 프로세스를 생성하고 파일을 메모리에 로딩한 후 EIP 레지스터 값을 ImageBase + AddressOfEntryPoint 값으로 세팅한다.
  • SectionAlignment, FileAlignment : 파일에서 섹션의 최소단위를 나타내는 것이 FileAlignment이고, 메모리에서 섹션의 최소단위를 나타내는 것이 SectionAlignment이다.(하나의 파일에서 FileAlignment와 SectionAlignment의 값은 같을 수도 있고 다를 수도 있으며, 파일/메모리의 섹션 크기는 반드시 각각 FileAlignment/SectionAlignment의 배수가 되어야 한다.)
  • SizeOfImage : PE 파일이 메모리에 로딩되었을 때 가상 메모리에서 PE Image가 차지하는 크기(일반적으로 파일의 크기와 메모리에 로딩된 크기는 다르다.)
  • SizeOfHeader : PE 헤더의 전체 크기(이 값 또한 FileAlignment의 배수여야 하며, 파일 시작에서 SizeOfHeader offset만큼 떨어진 위치에 첫 번째 섹션이 위치한다. )
  • Subsystem : 이 값을 보고 시스템 드라이버 파일(*.sys)인지, 일반 실행 파일(*.exe, *.dll)인지 구분할 수 있다.
1 Driver File 시스템 드라이버(ex. ntfs.sys)
2 GUI 파일 창 기반 애플리케이션(ex. notepad.exe)
3 CUI 파일 콘솔 기반 애플리케이션(ex. cmd.exe)
  • NumberOfRvaAndSizes : IMAGE_OPTIONAL_HEADER32 구조체의 마지막 멤버인 DataDirectory 배열의 개수를 나타낸다.(고정적인 16개가 아닐 수 있다.)
  • DataDirectory : IMAGE_DATA_DIRECTORY 구조체의 배열로, 배열의 각 항목마다 정의된 값을 가진다.
DataDirectory[0] = EXPORT Directory
DataDirectory[1] = IMPORT Directory
DataDirectory[2] = RESOURCE Directory
DataDirectory[3] = EXCEPTION Directory
DataDirectory[4] = SECURITY Directory
DataDirectory[5] = BASERELOC Directory
DataDirectory[6] = DEBUG Directory
DataDirectory[7] = COPYRIGHT Directory
DataDirectory[8] = GLOBALPTR Directory
DataDirectory[9] = TLS Directory
DataDirectory[A] = LOAD_CONFIG Directory
DataDirectory[B] = BOUND_IMPORT Directory
DataDirectory[C] = IAT Directory
DataDirectory[D] = DELAY_IMPORT Directory
DataDirectory[E] = COM_DESCRIPTOR Directory
DataDirectory[F] = Reserved Directory

출력 코드

 

IMAGE_DOS_HEADER 구조체 포인터 변수 선언

IMAGE_DOS_HEADER* idh = (IMAGE_DOS_HEADER*)buf;

 

32bit와 64bit 모두 NT header의 시작 오프셋 값을 알기 위해서는 IMAGE_DOS_HEADER 구조체의 e_lfanew 멤버의 값을 알아야 한다.

 

그렇기 때문에 공통으로 사용함으로 switch 문 이전에 선언해준다.

 

출력 부분

case OPERAND_NT32:
{
    IMAGE_NT_HEADERS32* inh32 = (IMAGE_NT_HEADERS32*)(buf + idh->e_lfanew);

    // 파일 포인터를 NT header 위치로 이동
    offset = set_file_offset(fp, idh->e_lfanew);

    printf("=============== [NT Header 32] ===============\n\n");
    printf("[%08X] - Signature[%zdbyte]\t\t\t: %08X\n\n", offset, sizeof(inh32->Signature), inh32->Signature);
    offset = get_file_offset(fp, sizeof(inh32->Signature));

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

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

    printf("[%08X] - TimeDateStamp[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->FileHeader.TimeDateStamp), inh32->FileHeader.TimeDateStamp);
    offset = get_file_offset(fp, sizeof(inh32->FileHeader.TimeDateStamp));

    printf("[%08X] - PointerToSymbolTable[%zdbyte]\t: %08X\n", offset, sizeof(inh32->FileHeader.PointerToSymbolTable), inh32->FileHeader.PointerToSymbolTable);
    offset = get_file_offset(fp, sizeof(inh32->FileHeader.PointerToSymbolTable));

    printf("[%08X] - NumberOfSymbols[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->FileHeader.NumberOfSymbols), inh32->FileHeader.NumberOfSymbols);
    offset = get_file_offset(fp, sizeof(inh32->FileHeader.NumberOfSymbols));

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

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

    printf("--------------- (OptionalHeader 32) ---------------\n");
    printf("[%08X] - Magic[%zdbyte]\t\t\t: %04X\n", offset, sizeof(inh32->OptionalHeader.Magic), inh32->OptionalHeader.Magic);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.Magic));

    printf("[%08X] - MajorLinkerVersion[%zdbyte]\t\t: %02X\n", offset, sizeof(inh32->OptionalHeader.MajorLinkerVersion), inh32->OptionalHeader.MajorLinkerVersion);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.MajorLinkerVersion));

    printf("[%08X] - MinorLinkerVersion[%zdbyte]\t\t: %02X\n", offset, sizeof(inh32->OptionalHeader.MinorLinkerVersion), inh32->OptionalHeader.MinorLinkerVersion);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.MinorLinkerVersion));

    printf("[%08X] - SizeofCode[%zdbyte]\t\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.SizeOfCode), inh32->OptionalHeader.SizeOfCode);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.SizeOfCode));

    printf("[%08X] - SizeofInitializedData[%zdbyte]\t: %08X\n", offset, sizeof(inh32->OptionalHeader.SizeOfInitializedData), inh32->OptionalHeader.SizeOfInitializedData);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.SizeOfInitializedData));

    printf("[%08X] - SizeOfUninitializedData[%zdbyte]\t: %08X\n", offset, sizeof(inh32->OptionalHeader.SizeOfUninitializedData), inh32->OptionalHeader.SizeOfUninitializedData);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.SizeOfUninitializedData));

    printf("[%08X] - AddressOfEntryPoint[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.AddressOfEntryPoint), inh32->OptionalHeader.AddressOfEntryPoint);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.AddressOfEntryPoint));

    printf("[%08X] - BaseOfCode[%zdbyte]\t\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.BaseOfCode), inh32->OptionalHeader.BaseOfCode);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.BaseOfCode));

    printf("[%08X] - BaseOfData[%zdbyte]\t\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.BaseOfData), inh32->OptionalHeader.BaseOfData);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.BaseOfData));

    printf("[%08X] - ImageBase[%zdbyte]\t\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.ImageBase), inh32->OptionalHeader.ImageBase);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.ImageBase));

    printf("[%08X] - SectionAlignment[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.SectionAlignment), inh32->OptionalHeader.SectionAlignment);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.SectionAlignment));

    printf("[%08X] - FileAlignment[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.FileAlignment), inh32->OptionalHeader.FileAlignment);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.FileAlignment));

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

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

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

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

    printf("[%08X] - MajorSubsystemVersion[%zdbyte]\t: %04X\n", offset, sizeof(inh32->OptionalHeader.MajorSubsystemVersion), inh32->OptionalHeader.MajorSubsystemVersion);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.MajorOperatingSystemVersion));

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

    printf("[%08X] - Win32VersionValue[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.Win32VersionValue), inh32->OptionalHeader.Win32VersionValue);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.Win32VersionValue));

    printf("[%08X] - SizeOfImage[%zdbyte]\t\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.SizeOfImage), inh32->OptionalHeader.SizeOfImage);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.SizeOfImage));

    printf("[%08X] - SizeOfHeaders[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.SizeOfHeaders), inh32->OptionalHeader.SizeOfHeaders);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.SizeOfHeaders));

    printf("[%08X] - CheckSum[%zdbyte]\t\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.CheckSum), inh32->OptionalHeader.CheckSum);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.CheckSum));

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

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

    printf("[%08X] - SizeOfStackReserve[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.SizeOfStackReserve), inh32->OptionalHeader.SizeOfStackReserve);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.SizeOfStackReserve));

    printf("[%08X] - SizeOfStackCommit[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.SizeOfStackCommit), inh32->OptionalHeader.SizeOfStackCommit);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.SizeOfStackCommit));

    printf("[%08X] - SizeOfHeapReserve[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.SizeOfHeapReserve), inh32->OptionalHeader.SizeOfHeapReserve);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.SizeOfHeapReserve));

    printf("[%08X] - SizeOfHeapCommit[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.SizeOfHeapCommit), inh32->OptionalHeader.SizeOfHeapCommit);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.SizeOfHeapCommit));

    printf("[%08X] - LoaderFlags[%zdbyte]\t\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.LoaderFlags), inh32->OptionalHeader.LoaderFlags);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.LoaderFlags));

    printf("[%08X] - NumberOfRvaAndSizes[%zdbyte]\t\t: %08X\n", offset, sizeof(inh32->OptionalHeader.NumberOfRvaAndSizes), inh32->OptionalHeader.NumberOfRvaAndSizes);
    offset = get_file_offset(fp, sizeof(inh32->OptionalHeader.NumberOfRvaAndSizes));

    /*for (int i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++)
    {
        printf("- DataDirectory[%d].VirtualAddress[%dbyte]\t:%08X\n", i, sizeof(inh32->OptionalHeader.DataDirectory[i].VirtualAddress), inh32->OptionalHeader.DataDirectory[i].VirtualAddress);
        printf("- DataDirectory[%d].Size[%dbyte]\t\t\t:%08X\n", i, sizeof(inh32->OptionalHeader.DataDirectory[i].Size), inh32->OptionalHeader.DataDirectory[i].Size);
    }
    */

    print_inh_ioh_datadirectory(fp, buf, OPERAND_NT32_DATADIRECTORY);

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

 

코드 설명은 32bit일 때의 코드로 설명한다.

(64bit일 때의 코드도 몇몇 멤버의 크기만 다를 뿐 동작 원리는 같다.)

 

32bit의 경우에는 IMAGE_NT_HEADER32로 선언해주고, 64bit의 경우에는 IMAGE_NT_HEADER64로 선언해준다.

 

출력 부분 코드는 Dos header에서처럼 파일 오프셋을 NT header의 시작 오프셋 값으로 설정하고, 값을 출력한 뒤 출력한 값의 크기만큼 오프셋을 옮기며 optional header의 멤버들까지 출력한다.

 

그 후 print_inh_ioh_datadirectory() 함수를 호출한다.

 

print_inh_ioh_datadirectory() 함수 역시 32bit인지 64bit인지에 따라 다르게 처리되도록 switch 문으로 나눠져 있다.

 

 

반응형

+ Recent posts