pe結構分析-解析pe頭(一)

 

 

// peFileAna.cpp : 定義控制檯應用程序的入口點。
//

// peFileAna.cpp : 定義控制檯應用程序的入口點。
//

#include "stdafx.h"

#include "file.h"
#include "malloc.h"


#define  in_file_name  "d:\\user32.dll"
#define out_file_name "d:\\2.exe"


IMAGE_SECTION_HEADER sectionHeaders[100] = { 0 };
int sectionNum = 0;

int readFileToBuff(char * filename, char ** buf, int * fileLen);
int writeBuffToFile(char * filename, char *buf, int fileLen);
int printFileHeader(char * filename);
int printSectionsInfo(BYTE  * firstSectionHeader, int sectionNum);
int getRfaFromRva(int rva);
int getSectionIndexOfRva(int rva);
int printExportTable(BYTE * dosheader, IMAGE_OPTIONAL_HEADER32 *  optionHeader);


int main()
{

	char *outfilebuf;
	int fileLeng = 0;

	readFileToBuff(in_file_name, &outfilebuf, &fileLeng);

	printFileHeader(outfilebuf);
	//getRfaFromRva(1002);

//	writeBuffToFile(out_file_name, outfilebuf, fileLeng);

	return 0;
}


int getRfaFromRva(int rva) {


	int sectionIndexOfRva = getSectionIndexOfRva(rva);

	if (sectionIndexOfRva >= sectionNum) {
		printf("get secttion index of rva fail ; \n");
		return 1;
	}

	printf(" rva section index = %d", sectionIndexOfRva);

	return rva - sectionHeaders[sectionIndexOfRva].VirtualAddress + sectionHeaders[sectionIndexOfRva].PointerToRawData;

	return 1;

}

int getSectionIndexOfRva(int rva) {

	int sectionIndex = 0; 
	int rvaIndex = 0;

	for (; sectionIndex < sectionNum; sectionIndex++) {
		if (rva > sectionHeaders[sectionIndex].VirtualAddress
			&&  rva < sectionHeaders[sectionIndex + 1].VirtualAddress) {
			rvaIndex = sectionIndex;
			break;

		}
	}
	return rvaIndex;
}

int printSectionsInfo(BYTE  * firstSectionHeader, int sectionNum) {

	int sectionNumIndex = 0;
	IMAGE_SECTION_HEADER * sectionHeader;

	printf("sections info ============================== \n");

	for (; sectionNumIndex < sectionNum; sectionNumIndex++) {
		char a[10] = { '\0' };
		sectionHeader = (IMAGE_SECTION_HEADER *)(firstSectionHeader + sectionNumIndex * sizeof(IMAGE_SECTION_HEADER));
		printf("section index:%d  =================  \n", sectionNumIndex);
		memcpy(a, sectionHeader->Name, 8);
		printf("section name =%s \n", a);
		printf("VirtualAddress =%xh \n", sectionHeader->VirtualAddress);
		printf("SizeOfRawData =%xh \n", sectionHeader->SizeOfRawData);
		printf("PointerToRawData =%xh \n", sectionHeader->PointerToRawData);
		memcpy(&sectionHeaders[sectionNumIndex], sectionHeader, sizeof(IMAGE_SECTION_HEADER));

	}

	return 1;


}


int printFileHeader(char * filename) {

	IMAGE_DOS_HEADER  *  dosHeader = (IMAGE_DOS_HEADER *)filename;

	printf("dos header info ---------------   \n");
	printf("e_lfanew = %xh \n", dosHeader->e_lfanew);

	IMAGE_NT_HEADERS32 * ntHeader = (IMAGE_NT_HEADERS32 *)((char *)dosHeader + dosHeader->e_lfanew);

	//printf("sign = %xh \n", ntHeader->Signature);

	IMAGE_FILE_HEADER * imageFileHeader = (IMAGE_FILE_HEADER *)((char *)ntHeader + 4);
	WORD NumberOfSections = imageFileHeader->NumberOfSections;
	printf("NumberOfSections = %xh \n", imageFileHeader->NumberOfSections);

	IMAGE_OPTIONAL_HEADER32 * optionHeader = (IMAGE_OPTIONAL_HEADER32 *)((BYTE *)imageFileHeader + 20);

	printf("AddressOfEntryPoint = %xh \n", optionHeader->AddressOfEntryPoint);
	printf("ImageBase = %xh \n", optionHeader->ImageBase);
	printf("SectionAlignment = %xh \n", optionHeader->SectionAlignment);
	printf("FileAlignment = %xh \n", optionHeader->FileAlignment);
	printf("SizeOfImage = %xh \n", optionHeader->SizeOfImage);
	printf("SizeOfHeaders = %xh \n", optionHeader->SizeOfHeaders);
	sectionNum = imageFileHeader->NumberOfSections;

	printSectionsInfo(((BYTE *)optionHeader) + sizeof(IMAGE_OPTIONAL_HEADER32), imageFileHeader->NumberOfSections);
	printExportTable((BYTE *)dosHeader, optionHeader);

	return  1;
}


int printExportTable(BYTE * dosheader, IMAGE_OPTIONAL_HEADER32 *  optionHeader) {

	int exportTableRva = optionHeader->DataDirectory[0].VirtualAddress;
	int rawOfExportTable = getRfaFromRva(exportTableRva);

	IMAGE_EXPORT_DIRECTORY * imageExportDir = (IMAGE_EXPORT_DIRECTORY *)(dosheader + rawOfExportTable);

	printf("exportTable name = %xh \n", imageExportDir->Name);
	printf("exportTable NumberOfNames = %xh\n", imageExportDir->NumberOfNames);

	BYTE *addressForFunction =(BYTE *) malloc(10 * 4);
	BYTE *addressForid = (BYTE *)malloc(10 * 2);


	int rawOfAddressOfName = getRfaFromRva(imageExportDir->AddressOfNames);
	int rawOfAddressOfId = getRfaFromRva(imageExportDir->AddressOfNameOrdinals);
	int rawOfAddressForFunction = getRfaFromRva(imageExportDir->AddressOfFunctions);

	for (int nameIndex = 0; nameIndex < imageExportDir->NumberOfNames; nameIndex++) {
		if (nameIndex > 10) break;

		DWORD addrRva = *(DWORD *)(dosheader + rawOfAddressForFunction + nameIndex * 4);
		DWORD  rawOfAddrRva = getRfaFromRva(addrRva);
		*((DWORD *) addressForFunction + nameIndex) = rawOfAddrRva;

		DWORD IdRva = *(DWORD *)(dosheader + rawOfAddressOfId + nameIndex * 4);
		DWORD  rawOfAddrRva = getRfaFromRva(addrRva);
		*((DWORD *)addressForFunction + nameIndex) = rawOfAddrRva;

	}


	
	for (int nameIndex = 0; nameIndex < imageExportDir->NumberOfNames; nameIndex++) {
		if (nameIndex > 10) break;

		DWORD nameRva = *(DWORD *)(dosheader + rawOfAddressOfName + nameIndex * 4);
		DWORD  rawOfNameRva = getRfaFromRva(nameRva);
		BYTE * name = dosheader + rawOfNameRva;
		printf("name = %s  ,funtion addr =%xh  \n", name, *(addressForFunction+ nameIndex));

		//WORD idRva = *(WORD *)(dosheader + rawOfAddressOfId + nameIndex * 2);


	}



	return 1;
}

int writeBuffToFile(char * filename, char *buf, int fileLen) {
	FILE * stream;
	stream = fopen(out_file_name, "wb");
	fwrite(buf, 1, fileLen, stream);
	fclose(stream);
	return 1;
}




int readFileToBuff(char * filename, char ** buf, int * fileLen) {

	//char *file1 = malloc(10000);
	//unsigned char buf[100000];
	char *p = 0;



	FILE *pf = fopen(filename, "rb");
	if (!pf)
	{
		printf("fail open file %s ", filename);
		return -1;
	}
	
	fseek(pf, 0, SEEK_END); // 移到文件末尾
	int fileleng = ftell(pf);
	rewind(pf);
	p = (char *)malloc(fileleng);

	if (!p) {
		printf("mallloc fail ");
		return 1;
	}


	fread(p, 1, fileleng, pf);

	printf("size = %d\n", ftell(pf));
	*fileLen = fileleng;
	*buf = p;

	return 1;

}


 

 

 

// stdafx.h : 標準系統包含文件的包含文件,
// 或是經常使用但不常更改的
// 特定於項目的包含文件
//


// file.h  
typedef unsigned short WORD;
typedef  unsigned long LONG;
typedef unsigned long DWORD;
typedef unsigned char BYTE;
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16

typedef struct {      // DOS .EXE header
	WORD   e_magic;                     // Magic number
	WORD   e_cblp;                      // Bytes on last page of file
	WORD   e_cp;                        // Pages in file
	WORD   e_crlc;                      // Relocations
	WORD   e_cparhdr;                   // Size of header in paragraphs
	WORD   e_minalloc;                  // Minimum extra paragraphs needed
	WORD   e_maxalloc;                  // Maximum extra paragraphs needed
	WORD   e_ss;                        // Initial (relative) SS value
	WORD   e_sp;                        // Initial SP value
	WORD   e_csum;                      // Checksum
	WORD   e_ip;                        // Initial IP value
	WORD   e_cs;                        // Initial (relative) CS value
	WORD   e_lfarlc;                    // File address of relocation table
	WORD   e_ovno;                      // Overlay number
	WORD   e_res[4];                    // Reserved words
	WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
	WORD   e_oeminfo;                   // OEM information; e_oemid specific
	WORD   e_res2[10];                  // Reserved words
	LONG   e_lfanew;                    // File address of new exe header
} IMAGE_DOS_HEADER;



typedef struct _IMAGE_DATA_DIRECTORY {
	DWORD   VirtualAddress;
	DWORD   Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;


typedef struct _IMAGE_FILE_HEADER {
	WORD    Machine;
	WORD    NumberOfSections;
	DWORD   TimeDateStamp;
	DWORD   PointerToSymbolTable;
	DWORD   NumberOfSymbols;
	WORD    SizeOfOptionalHeader;
	WORD    Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

typedef struct _IMAGE_EXPORT_DIRECTORY {
	DWORD   Characteristics;
	DWORD   TimeDateStamp;
	WORD    MajorVersion;
	WORD    MinorVersion;
	DWORD   Name;
	DWORD   Base;
	DWORD   NumberOfFunctions;
	DWORD   NumberOfNames;
	DWORD   AddressOfFunctions;     // RVA from base of image
	DWORD   AddressOfNames;         // RVA from base of image
	DWORD   AddressOfNameOrdinals;  // RVA from base of image
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

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;

typedef struct _IMAGE_NT_HEADERS {
	DWORD Signature;
	IMAGE_FILE_HEADER FileHeader;
	IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
#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;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章