반응형
#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 값을 출력하고 출력한 값만큼 파일 오프셋을 이동시킨다.
반응형
'toy project > Reversing' 카테고리의 다른 글
[Toy Project] PE Viewer 툴 만들기(6) convert_rva_to_raw.c (0) | 2023.07.26 |
---|---|
[Toy Project] PE Viewer 툴 만들기(5) print_section_header.c (0) | 2023.07.26 |
[Toy Project] PE Viewer 툴 만들기(3) print_nt_header.c (0) | 2023.07.26 |
[Toy Project] PE Viewer 툴 만들기(2) print_dos_header.c (0) | 2023.07.26 |
[Toy Project] PE Viewer 툴 만들기(1) header.h (0) | 2023.07.25 |