특이사항 보다는 안써본함수가 있어서 그거에 대한 내용은 주석에다가 달아두었고 ,
PE 포맷임을 확인하는 signature를 확인하고 IMAGE_FILE_HEADER를 뽑아주고.
magic을 기준으로 PE 32, PE32+(64bit)를 나눈뒤 IMAGE_OPTIONAL_HEADER값들을 뽑아주는 형식으로 진행된다
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include “..\include\headers.h”
#include “..\include\utils.h”
#include “..\include\codes.h”
int main(int argc,char** argv[])
{ //인자값 체크
if(argc <2)
{
printf(“Usage: %s file\n”, argv[0]);
}
const char* filename = argv[1];
FILE* file = fopen(filename, “rb”);
long size = 0;
char* data;
if(!file)
{ //파일포맷이 맞지않을때 오류
fprintf(stderr, “Failed to open file. \n”);
return EXIT_FAILURE;
}
fseek(file,0,SEEK_END);
// fseek() 함수 레퍼런스 , 파일에서 위치 찾는 함수
//http://www.tipssoft.com/bulletin/board.php?bo_table=old_bbs&wr_id=298
size = ftell(file); //ftell() : 현재사용하는 파일 포인터의 작업위치 알려줌, 보통 파일크기 알아낼때 사용
rewind(file); //파일의 읽기/쓰기 위치를 처음으로 다시 초기화 시킴
data = (char*)malloc(size * sizeof(char));
if(data == NULL)
{
fprintf(stderr, “Failed to allocate memory/ \n”);
}
int bytes_read = fread(data, sizeof(char), size, file);
if(bytes_read < size)
{
perror(“Failed to read file.\n”);
}
if(size <= 133) // 최소한의 PE파일 크기 check
{
printf(“Not a valid PE file. \n”);
return EXIT_SUCCESS;
}
union
{
char* ptr;
int* num;
}t;
//union 레퍼런스
//http://forum.falinux.com/zbxe/index.php?document_srl=557139&mid=lecture_tip
t.ptr = &data[60];
if((*t.number + 3 ) >size) //범위check
{
printf(“Not a valid PE file\n”);
return EXIT_SUCCESS;
}
char pe_sig[4] = {data[*t.num], data[*t.num+1],
data[t.num+2], data[*t.num+3]};
union // PE Header 유니온 설정
{
PE_Header* pe_head;
char* data;
}u;
u.data=&data[*t.num];
if(strcmp(pe_sig, “PE”) !=0) //PE signature확인
{
printf(“Not a valid PE file.\n”);
return EXIT_SUCCESS;
}
time_t timestamp = (time_t)u.pe_head->TimeStamp;
printf(“%s:\n\n”, argv[1]);
// information start
printf(“PE HEADER INFORMATION\n”);
printf(“Machine : %s\n”, read_machine_type(u.pe_head));
printf(“NumberOfSections: %i\n”, u.pe_head->NumberOfSections);
printf(“TimeDateStamp: %s”, ctime(×tamp));
printf(“PointerToSymbolTable: %x\n”, u.pe_head->PointerToSymbolTable);
printf(“NumberOfSymbols: %i\n”, u.pe_head->NumberOfSymbols);
printf(“SizeOfOptionalHeader: %i\n”, u.pe_head->SizeOfOptionalHeader);
printf(“Characteristics:\n”);
print_characteristics(read_characeteristics(u.pe_head));
if(u.pe_head->SizeOfOptionalHeader >0)
{
printf(“\nPE OPTIONAL HEADER INFORMATION”);
int opt_head_start = *t.num+(24 * sizeof(char));
int opt_head_end = opt_head_start + u.pe_head->SizeOfOptionalHeader;
char magic_str[2] = {data[opt_head_start], data[opt_head_start+1]};
union
{
char* str;
short* magic;
}v;
//magic을 기준으로 PE32 PE64 구분
v.str=magic_str;
if(*v.magic==0x10b)
{
//PE32
printf( “PE32\n”);
union
{
PE_Optional_Header* pe_opt_head;
char* data;
}w; // Optional header 기준
w.data = &data[opt_head_start];
printf("MajorLinkerVersion: %i\n", w.pe_opt_head->MajorLinkerVersion);
printf("MinorLinkerVersion: %i\n", w.pe_opt_head->MinorLinkerVersion);
printf("SizeOfCode: %i\n", w.pe_opt_head->SizeOfCode);
printf("SizeOfInitializedData: %i\n", w.pe_opt_head->SizeOfInitializedData);
printf("SizeOfUninitializedData: %i\n", w.pe_opt_head->SizeOfUninitializedData);
printf("AddressOfEntryPoint: %#x\n", w.pe_opt_head->AddressOfEntryPoint);
printf("BaseOfCode: %#x\n", w.pe_opt_head->BaseOfCode);
printf("ImageBase: %#x\n", w.pe_opt_head->ImageBase);
printf("\n");
printf("SectionAlignment: %i\n", w.pe_opt_head->SectionAlignment);
printf("FileAlignment: %i\n", w.pe_opt_head->FileAlignment);
printf("MajorOperatingSystemVersion: %i\n", w.pe_opt_head->MajorOperatingSystemVersion);
printf("MinorOperatingSystemVersion: %i\n", w.pe_opt_head->MinorOperatingSystemVersion);
printf("MajorImageVersion: %i\n", w.pe_opt_head->MajorImageVersion);
printf("MinorImageVersion: %i\n", w.pe_opt_head->MinorImageVersion);
printf("MajorSubsystemVersion: %i\n", w.pe_opt_head->MajorSubsystemVersion);
printf("MinorSubsystemVersion: %i\n", w.pe_opt_head->MinorSubsystemVersion);
printf("Win32VersionValue: %i\n", w.pe_opt_head->Win32VersionValue);
printf("SizeOfImage: %i\n", w.pe_opt_head->SizeOfImage);
printf("SizeOfHeaders: %i\n", w.pe_opt_head->SizeOfHeaders);
printf("CheckSum: %i\n", w.pe_opt_head->CheckSum);
printf("Subsystem: %s\n", read_windows_subsystem_pe32(w.pe_opt_head));
printf("DLLCharacteristics:\n");
print_dll_characteristics(read_dll_characteristics_pe32(w.pe_opt_head));
printf("SizeOfStackReserve: %i\n", w.pe_opt_head->SizeOfStackReserve);
printf("SizeOfStackCommit: %i\n", w.pe_opt_head->SizeOfStackCommit);
printf("SizeOfHeapReserve: %i\n", w.pe_opt_head->SizeOfHeapReserve);
printf("LoaderFlags: %i\n", w.pe_opt_head->LoaderFlags);
printf("NumberOfRvaAndSizes: %i\n", w.pe_opt_head->NumberOfRvaAndSizes);
}
else if(*v.magic == 0x20b)
{
// PE32+ 64비트 기준
printf("(PE32+)\n");
union
{
PE_Optional_Header_Plus* pe_opt_head;
char* data;
}w; //optional header기준
w.data = &data[opt_head_start];
printf("MajorLinkerVersion: %i\n", w.pe_opt_head->MajorLinkerVersion);
printf("MinorLinkerVersion: %i\n", w.pe_opt_head->MinorLinkerVersion);
printf("SizeOfCode: %i\n", w.pe_opt_head->SizeOfCode);
printf("SizeOfInitializedData: %i\n", w.pe_opt_head->SizeOfInitializedData);
printf("SizeOfUninitializedData: %i\n", w.pe_opt_head->SizeOfUninitializedData);
printf("AddressOfEntryPoint: %#x\n", w.pe_opt_head->AddressOfEntryPoint);
printf("BaseOfCode: %#x\n", w.pe_opt_head->BaseOfCode);
printf("ImageBase: %#x\n", w.pe_opt_head->ImageBase);
printf("\n");
printf("SectionAlignment: %i\n", w.pe_opt_head->SectionAlignment);
printf("FileAlignment: %i\n", w.pe_opt_head->FileAlignment);
printf("MajorOperatingSystemVersion: %i\n", w.pe_opt_head->MajorOperatingSystemVersion);
printf("MinorOperatingSystemVersion: %i\n", w.pe_opt_head->MinorOperatingSystemVersion);
printf("MajorImageVersion: %i\n", w.pe_opt_head->MajorImageVersion);
printf("MinorImageVersion: %i\n", w.pe_opt_head->MinorImageVersion);
printf("MajorSubsystemVersion: %i\n", w.pe_opt_head->MajorSubsystemVersion);
printf("MinorSubsystemVersion: %i\n", w.pe_opt_head->MinorSubsystemVersion);
printf("Win32VersionValue: %i\n", w.pe_opt_head->Win32VersionValue);
printf("SizeOfImage: %i\n", w.pe_opt_head->SizeOfImage);
printf("SizeOfHeaders: %i\n", w.pe_opt_head->SizeOfHeaders);
printf("CheckSum: %i\n", w.pe_opt_head->CheckSum);
printf("Subsystem: %s\n", read_windows_subsystem_pe32_plus(w.pe_opt_head));
printf("DLLCharacteristics:\n");
print_dll_characteristics(read_dll_characteristics_pe32_plus(w.pe_opt_head));
printf("SizeOfStackReserve: %i\n", w.pe_opt_head->SizeOfStackReserve);
printf("SizeOfStackCommit: %i\n", w.pe_opt_head->SizeOfStackCommit);
printf("SizeOfHeapReserve: %i\n", w.pe_opt_head->SizeOfHeapReserve);
printf("LoaderFlags: %i\n", w.pe_opt_head->LoaderFlags);
printf("NumberOfRvaAndSizes: %i\n", w.pe_opt_head->NumberOfRvaAndSizes);
}
}
free(data);
return EXIT_SUCCESS;
}
'과거의 컴퓨터 공부 > PE Viewer 다시만들기 ' 카테고리의 다른 글
(PEViewer)utils.h (0) | 2015.06.02 |
---|---|
(PEViewer) codes.h (0) | 2015.06.01 |
(PEViewer)headers.h (0) | 2015.06.01 |
PE viewer 다시 만들어보기 (0) | 2015.05.31 |