pe文件:一个PE文件的学习程序



#pragma comment( lib, "Imagehlp.lib" )
#<windows.h>
#<Imagehlp.h>
#<memory.h>
#<iostream>
using std;

AnalysisPE
{
//些辅助宏定义;
# NUMOFSECTION pNTHeader->FileHeader.NumberOfSections

public:
AnalysisPE{}
AnalysisPE(PTCHAR iname){
PEName(iname);
}
~AnalysisPE{
_UnLoadFile;
}
VOID PEName(PTCHAR iname){
name = iname;
hFile=NULL;
hFileMapping=NULL;
hMapView=NULL;

(!_LoadFile){
cout << "加载文件失败!\n";
;
}
_walkThroughPE;
}
BOOL isPEFile{ isPE; }

VOID prSectionHeaders;
VOID prNTHeaderInfo;
VOID prImageFileHeaderInfo;
VOID prImageOptionalHeaderInfo;
VOID prImportInfo;

private:
BOOL _LoadFile; //把要分析文件加载到内存;
VOID _UnLoadFile;
VOID _walkThroughPE; //粗略地遍历PE文件;
DWORD _getRawAddress(DWORD pVirtualAddress, DWORD pPEHeader);
private:
PTCHAR name;
HANDLE hFile;
HANDLE hFileMapping;
HANDLE hMapView;

BOOL isPE;
PIMAGE_DOS_HEADER pDOSHeader;
PIMAGE_NT_HEADERS pNTHeader;
PIMAGE_SECTION_HEADER pSectionHeader;
};
VOID AnalysisPE::prImportInfo
{
cout << "\n【Import information!】\n";
PIMAGE_OPTIONAL_HEADER pOpn_header = &pNTHeader->OptionalHeader;
DWORD pFileHeader = (DWORD)&pNTHeader->FileHeader;
DWORD pAddress = pOpn_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
DWORD rawAddress = _getRawAddress(pAddress, (DWORD)pFileHeader);
PIMAGE_IMPORT_DESCRIPTOR pImportDec = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pDOSHeader + rawAddress);

while(1)
{
IMAGE_IMPORT_DESCRIPTOR cmp;
mem(&cmp, 0, (IMAGE_IMPORT_DESCRIPTOR));
( 0 memcmp(&cmp, pImportDec, (IMAGE_IMPORT_DESCRIPTOR)))
;

DWORD* desp = (DWORD*)((DWORD)pDOSHeader + _getRawAddress(pImportDec->OriginalFirstThunk, (DWORD)pFileHeader));
DWORD* addr = (DWORD*)((DWORD)pDOSHeader + _getRawAddress(pImportDec->FirstThunk, (DWORD)pFileHeader));

(*desp || *addr)
{
char* dllName = (char*)((DWORD)pDOSHeader + _getRawAddress(pImportDec->Name, (DWORD)pFileHeader));
cout << "\n\n" << dllName << endl;

while(*desp || *addr)
{
(IMAGE_ORDINAL_FLAG&*desp) //序号导入
cout << IMAGE_ORDINAL(*desp)<<"\t\t";
//名字导入
{
PIMAGE_IMPORT_BY_NAME pName = (PIMAGE_IMPORT_BY_NAME)((DWORD)pDOSHeader + _getRawAddress(*desp, (DWORD)pFileHeader));
cout << pName->H << "\t" << (char*)(&pName->Name) << "\t";
}
cout << *addr << endl;

desp = (DWORD*)((DWORD)desp + (DWORD));
addr = (DWORD*)((DWORD)addr + (DWORD));
}
}
pImportDec = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pImportDec + (IMAGE_IMPORT_DESCRIPTOR));
}
}

//文件对齐(FileAlignment)和内存对齐(SectionAlignment)不样(见以下IMAGE_OPTIONAL_HEADER中分析)所以这个是有必要
DWORD AnalysisPE::_getRawAddress(DWORD pVirtualAddress, DWORD pPEHeader)
{
DWORD rt=-1;
sectionNum = PIMAGE_FILE_HEADER(pPEHeader)->NumberOfSections;
DWORD pSectionAddress = pPEHeader + (IMAGE_FILE_HEADER) + PIMAGE_FILE_HEADER(pPEHeader)->SizeOfOptionalHeader;
for( i=0; i<sectionNum; i)
{
PIMAGE_SECTION_HEADER pSection = (PIMAGE_SECTION_HEADER)pSectionAddress;
DWORD begin = pSection->VirtualAddress;
DWORD end = pSection->VirtualAddress + pSection->Misc.VirtualSize;
(pVirtualAddress<end && pVirtualAddress>=begin)
{
rt = pSection->PoerToRawData + pVirtualAddress - begin;
;
}
pSectionAddress (IMAGE_SECTION_HEADER);
}
rt;
}
// 相关结构体如下(可以在WinNT.h中找到):
//
//typedef struct _IMAGE_OPTIONAL_HEADER {
// //
// // Standard fields.
// //
//
// WORD Magic;
// BYTE MajorLinkerVersion;
// BYTE MinorLinkerVersion;
// DWORD SizeOfCode;
// DWORD SizeOfInitializedData;
// DWORD SizeOfUninitializedData;
// DWORD AddressOfEntryPo;
// DWORD BaseOfCode;
// DWORD BaseOfData;
//
// //
// // NT additional fields.
// //
//
// DWORD ImageBase;
// DWORD SectionAlignment;
// DWORD FileAlignment;
// WORD MajorOperatingVersion;
// WORD MinorOperatingVersion;
// 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;
VOID AnalysisPE::prImageOptionalHeaderInfo
{
(isPE!=TRUE)
;
cout << "\n----Information provided by IMAGE_OPTIONAL_HEADER as Follows:\n ";
PIMAGE_OPTIONAL_HEADER pOpn_header = &pNTHeader->OptionalHeader;
cout << "Standard fields.\n";
cout << "SizeOfInitializedData is : " << pOpn_header->SizeOfInitializedData << endl;
cout << "SizeOfUninitializedData is : " << pOpn_header->SizeOfUninitializedData << endl;
cout << "AddressOfEntryPo is : " << pOpn_header->AddressOfEntryPo << endl;
cout << "NT additional fields.\n";
cout << "ImageBase is : " << pOpn_header->ImageBase << endl;
cout << "SectionAlignment is : " << pOpn_header->SectionAlignment << endl;
cout << "FileAlignment is : " << pOpn_header->FileAlignment << endl;
cout << "MajorOperatingVersion is : " << pOpn_header->MajorOperatingVersion << endl;
cout << "MinorOperatingVersion is : " << pOpn_header->MinorOperatingVersion << endl;
cout << "SizeOfImage is : " << pOpn_header->SizeOfImage << endl;
cout << "SizeOfHeaders is : " << pOpn_header->SizeOfHeaders << endl;

(IMAGE_SUBSYSTEM_WINDOWS_GUIpOpn_header->Subsystem)
cout << "Image runs in the Windows GUI subsystem.\n";
(IMAGE_SUBSYSTEM_WINDOWS_CUIpOpn_header->Subsystem)
cout << "Image runs in the Windows character subsystem.\n";
}

// 相关结构体如下(可以在WinNT.h中找到):
//
//typedef struct _IMAGE_FILE_HEADER {
// WORD Machine;
// WORD NumberOfSections;
// DWORD TimeDateStamp;
// DWORD PoerToSymbolTable;
// DWORD NumberOfSymbols;
// WORD SizeOfOptionalHeader;
// WORD Characteristics;
//} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
//

VOID AnalysisPE::prImageFileHeaderInfo
{
(isPE!=TRUE)
;
cout << "\n----Information provided by IMAGE_FILE_HEADER as Follows:\n ";

cout << "Machine is : " << pNTHeader->FileHeader.Machine << " ";
(IMAGE_FILE_MACHINE_I386 pNTHeader->FileHeader.Machine)
cout << ", that means Intel 386. \n";
cout << "NumberOfSections is : " << pNTHeader->FileHeader.NumberOfSections << endl;
cout << "TimeDateStamp is : " << pNTHeader->FileHeader.TimeDateStamp << endl;
cout << "Characteristics is : " << pNTHeader->FileHeader.Characteristics << endl;
//对Characteristics个研究
(IMAGE_FILE_EXECUTABLE_IMAGE&pNTHeader->FileHeader.Characteristics)
cout << "File is executable\n";
(IMAGE_FILE_DLL&pNTHeader->FileHeader.Characteristics)
cout << "File is a DLL.\n";
}

VOID AnalysisPE::prNTHeaderInfo
{
cout << "\n=\n"
<< "Analysis NT header: \n";
prImageFileHeaderInfo;
prImageOptionalHeaderInfo;
}



VOID AnalysisPE::prSectionHeaders
{
(isPE!=TRUE)
;
cout << "\n=\n"
<< "PE Section headers:\n";
cout << "There are " << NUMOFSECTION << " sections in this PE!\n";
cout << "\nname\tsize\taddr\tread\twrite\texcute\n";
PIMAGE_SECTION_HEADER pSH = pSectionHeader;
for( i=0; i<NUMOFSECTION; i)
{
cout <<pSH->Name<< "\t"
<< pSH->SizeOfRawData << "\t"
<< pSH->VirtualAddress << "\t"
<< (pSH->Characteristics&IMAGE_SCN_MEM_READ? "true" : "false") << "\t"
<< (pSH->Characteristics&IMAGE_SCN_MEM_WRITE? "true" : "false") << "\t"


<< (pSH->Characteristics&IMAGE_SCN_MEM_EXECUTE? "true" : "false") << endl;
pSH = (PIMAGE_SECTION_HEADER)((DWORD)pSH + (IMAGE_SECTION_HEADER));
}
}

VOID AnalysisPE::_walkThroughPE
{
//文件装载起始位置就是DOS头;
pDOSHeader = (PIMAGE_DOS_HEADER)hMapView;
(IMAGE_DOS_SIGNATURE != pDOSHeader->e_magic){ //判断DOS标识是否正确
cout << "not PE file because of the DOS Magic number is not right!\n";
isPE = FALSE;
;
}

//DOS头中e_lfa就是NT头相对虚拟地址RVA;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)hMapView + pDOSHeader->e_lfa);
(IMAGE_NT_SIGNATURE != pNTHeader->Signature){ //判断PE标识是否正确
cout << "not PE file because of the NT Signature is not right\n";
isPE = FALSE;
;
}

isPE = TRUE; //是这是个PE文件

//得到节表(Section Table)地址
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pNTHeader + (IMAGE_NT_HEADERS));
}

BOOL AnalysisPE::_LoadFile
{
BOOL Flag = TRUE;
__try{

hFile = CreateFile(
this->name,
GENERIC_READ|GENERIC_EXECUTE ,
0,NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);

hFileMapping = CreateFileMapping(
hFile, NULL, PAGE_EXECUTE_READ,
0, 0, TEXT("testdll.dll"));

hMapView = MapViewOfFile(
hFileMapping ,
FILE_MAP_EXECUTE|FILE_MAP_READ,
0, 0, 0);
}
__finally{

(INVALID_HANDLE_VALUEhFile){
Flag = FALSE;
cout << "Error handle: create file fail!\n";
}

(NULL hFileMapping){
Flag = FALSE;
cout << "Error to create file mapping!\n";
}

(NULL hMapView){
Flag = FALSE;
cout << "Error to maping view of file!\n";
}
}
Flag;
}
VOID AnalysisPE::_UnLoadFile
{
(NULL!=hMapView)
UnmapViewOfFile(hMapView);
(NULL!=hFileMapping)
CloseHandle(hFileMapping);
( INVALID_HANDLE_VALUE!=hFile || NULL!=hFile )
CloseHandle(hFile);
}
void
{
AnalysisPE test;
test.PEName(TEXT("c:\\aa.exe")); //这里是想要测试PE文件
cout << (test.isPEFileTRUE ? "yes, it's PE" : "Shit, not a PE at all!") << endl;
test.prNTHeaderInfo;
test.prSectionHeaders;
test.prImportInfo;
system("pause");
}
Tags:  pe文件免杀器 pe文件免杀 pe文件免杀会员版 pe文件

延伸阅读

最新评论

发表评论