📄 pe.cpp
字号:
#include <windows.h>
#include <stdio.h>
/* DetectPe(char *) Written by Lu Lin. 1999.8.2
Only tested on MS complier and linker.
Entery :
parameter *p: point to the file name. eg. "c:\\command.com"
return :
true if the file is in PE format.
false if the file is not a PE file.
*/
BOOL DetectPe(char *p,IMAGE_NT_HEADERS *pNTHdr,IMAGE_SECTION_HEADER *pSectionHdr)
{
HANDLE hf; //handle for the file detecting
WORD ppe;
DWORD res;
PIMAGE_DOS_HEADER dosHeader;
hf=CreateFile(p,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if (hf==INVALID_HANDLE_VALUE)
{
GetLastError();
return 0;
}
if (!SetFilePointer(hf,0x3c,0,FILE_BEGIN))
{
CloseHandle(hf);
return 0;
}
if (!ReadFile(hf,&ppe,2,&res,0))
{
CloseHandle(hf);
return 0;
}
if (res!=2)
{
CloseHandle(hf);
return 0;
}
if (!SetFilePointer(hf,(long)ppe,0,FILE_BEGIN))
{
CloseHandle(hf);
return 0;
}
if (!ReadFile(hf,pNTHdr,sizeof(IMAGE_NT_HEADERS),&res,0))
{
CloseHandle(hf);
return 0;
}
if (res!=sizeof(IMAGE_NT_HEADERS))
{
CloseHandle(hf);
return 0;
}
for(int i=0;i<pNTHdr->FileHeader.NumberOfSections;i++)
{
if (!ReadFile(hf,pSectionHdr+i,sizeof(IMAGE_SECTION_HEADER),&res,0))
{
CloseHandle(hf);
return 0;
}
if (res!=sizeof(IMAGE_SECTION_HEADER))
{
CloseHandle(hf);
return 0;
}
}
CloseHandle(hf);
if (pNTHdr->Signature!=0x4550)
return 0;
return 1;
}
void OutputNTHdr(IMAGE_NT_HEADERS *NTHdr)
{
char *DirectoryData[]={
"[Export table address ]",
"[Import table address ]",
"[Resource table address ]",
"[Exception table address ]",
"[Certificate table address ]",
"[Base relocation table ]",
"[Debugging information starting ]",
"[Architecture-specific data ]",
"[Global pointer register ]",
"[Thread local storage (TLS) table ]",
"[Load configuration table ]",
"[Bound import table ]",
"[Import address table ]",
"[Delay import descriptor ]",
"[COM+ runtime header ]",
"[RESERVED ]"
};
printf("\n");
printf("Signature : %08X\n",NTHdr->Signature );
printf("Machine : %04X\n",NTHdr->FileHeader.Machine );
printf("NumberOfSections : %04X\n",NTHdr->FileHeader.NumberOfSections );
printf("TimeDateStamp : %08X\n",NTHdr->FileHeader.TimeDateStamp );
printf("PointerToSymbolTable : %08X\n",NTHdr->FileHeader.PointerToSymbolTable );
printf("NumberOfSymbols : %08X\n",NTHdr->FileHeader.NumberOfSymbols );
printf("SizeOfOptionalHeader : %04X\n",NTHdr->FileHeader.SizeOfOptionalHeader );
printf("Characteristics : %04X\n",NTHdr->FileHeader.Characteristics );
printf("\n");
printf("Magic : %04X\n",NTHdr->OptionalHeader.Magic );
printf("MajorLinkerVersion : %02X\n",NTHdr->OptionalHeader.MajorLinkerVersion );
printf("MinorLinkerVersion : %02X\n",NTHdr->OptionalHeader.MinorLinkerVersion );
printf("SizeOfCode : %08X\n",NTHdr->OptionalHeader.SizeOfCode );
printf("SizeOfInitializedData : %08X\n",NTHdr->OptionalHeader.SizeOfInitializedData );
printf("SizeOfUninitializedData : %08X\n",NTHdr->OptionalHeader.SizeOfUninitializedData );
printf("AddressOfEntryPoint : %08X\n",NTHdr->OptionalHeader.AddressOfEntryPoint );
printf("BaseOfCode : %08X\n",NTHdr->OptionalHeader.BaseOfCode );
printf("BaseOfData : %08X\n",NTHdr->OptionalHeader.BaseOfData );
printf("ImageBase : %08X\n",NTHdr->OptionalHeader.ImageBase );
printf("SectionAlignment : %08X\n",NTHdr->OptionalHeader.SectionAlignment );
printf("FileAlignment : %08X\n",NTHdr->OptionalHeader.FileAlignment );
printf("MajorOperatingSystemVersion : %04X\n",NTHdr->OptionalHeader.MajorOperatingSystemVersion );
printf("MinorOperatingSystemVersion : %04X\n",NTHdr->OptionalHeader.MinorOperatingSystemVersion );
printf("MajorImageVersion : %04X\n",NTHdr->OptionalHeader.MajorImageVersion );
printf("MinorImageVersion : %04X\n",NTHdr->OptionalHeader.MinorImageVersion );
printf("MajorSubsystemVersion : %04X\n",NTHdr->OptionalHeader.MajorSubsystemVersion );
printf("MinorSubsystemVersion : %04X\n",NTHdr->OptionalHeader.MinorSubsystemVersion );
printf("Win32VersionValue : %08X\n",NTHdr->OptionalHeader.Win32VersionValue );
printf("SizeOfImage : %08X\n",NTHdr->OptionalHeader.SizeOfImage );
printf("SizeOfHeaders : %08X\n",NTHdr->OptionalHeader.SizeOfHeaders );
printf("CheckSum : %08X\n",NTHdr->OptionalHeader.CheckSum );
printf("Subsystem: %04X\n",NTHdr->OptionalHeader.Subsystem);
printf("DllCharacteristics : %04X\n",NTHdr->OptionalHeader.DllCharacteristics );
printf("SizeOfStackReserve : %08X\n",NTHdr->OptionalHeader.SizeOfStackReserve );
printf("SizeOfStackCommit : %08X\n",NTHdr->OptionalHeader.SizeOfStackCommit );
printf("SizeOfHeapReserve : %08X\n",NTHdr->OptionalHeader.SizeOfHeapReserve );
printf("SizeOfHeapCommit : %08X\n",NTHdr->OptionalHeader.SizeOfHeapCommit );
printf("LoaderFlags : %08X\n",NTHdr->OptionalHeader.LoaderFlags );
printf("NumberOfRvaAndSizes : %08X\n\n",NTHdr->OptionalHeader.NumberOfRvaAndSizes );
for(DWORD i=0;i<NTHdr->OptionalHeader.NumberOfRvaAndSizes;i++)
{
printf("%s.VirtualAddress : %08X\n",DirectoryData[i],NTHdr->OptionalHeader.DataDirectory[i].VirtualAddress );
printf("%s.Size : %08X\n",DirectoryData[i],NTHdr->OptionalHeader.DataDirectory[i].Size );
}
}
void OutputSectionHdr(IMAGE_SECTION_HEADER *pSectionHdr,int Num)
{
for(int i=0;i<Num;i++)
{
printf("%s\n",pSectionHdr[i].Name);
printf("PhysicalAddress/VirtualSize : %08X\n",pSectionHdr[i].Misc );
printf("VirtualAddress : %08X\n",pSectionHdr[i].VirtualAddress );
printf("SizeOfRawData : %08X\n",pSectionHdr[i].SizeOfRawData );
printf("PointerToRawData : %08X\n",pSectionHdr[i].PointerToRawData );
printf("PointerToRelocations : %08X\n",pSectionHdr[i].PointerToRelocations );
printf("PointerToLinenumbers : %08X\n",pSectionHdr[i].PointerToLinenumbers );
printf("NumberOfRelocations : %04X\n",pSectionHdr[i].NumberOfRelocations );
printf("NumberOfLinenumbers : %04X\n",pSectionHdr[i].NumberOfLinenumbers );
printf("Characteristics : %08X\n",pSectionHdr[i].Characteristics );
}
}
//这个函数找到引入表的虚拟地址和文件相对物理地址并返回虚拟地址和文件物理地址的差值,因为PE文件里几乎所有的指针都是虚拟地址,
//所以要进行一下转换,把虚拟地址转换为文件相对物理地址,然后才能读取。
DWORD LookforImportTable(IMAGE_NT_HEADERS *pNTHdr,IMAGE_SECTION_HEADER *pSectionHdr,DWORD &RAV_Import,DWORD &PA_Import)
{
DWORD i=0;
RAV_Import=pNTHdr->OptionalHeader.DataDirectory[1].VirtualAddress;
while(pSectionHdr[i].VirtualAddress<=RAV_Import)
i++;
PA_Import=RAV_Import-pSectionHdr[i-1].VirtualAddress+pSectionHdr[i-1].PointerToRawData;
return RAV_Import-PA_Import;
}
BOOL ReadImportTable(char *p,DWORD RAVOffset,DWORD PhOffset)
{
HANDLE hf; //handle for the file detecting
DWORD res;
DWORD Cnt=0,Cnt1;
IMAGE_IMPORT_DESCRIPTOR Imp;
char ch;
DWORD PhThunk;
IMAGE_THUNK_DATA ThunkData;
IMAGE_IMPORT_BY_NAME IName;
hf=CreateFile(p,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if (hf==INVALID_HANDLE_VALUE)
{
GetLastError();
return 0;
}
if (!SetFilePointer(hf,PhOffset,0,FILE_BEGIN))
{
CloseHandle(hf);
return 0;
}
ReadFile(hf,&Imp,sizeof(IMAGE_IMPORT_DESCRIPTOR),&res,0);
while(Imp.OriginalFirstThunk||Imp.TimeDateStamp||Imp.ForwarderChain||Imp.Name||Imp.FirstThunk)
{
printf("OriginalFirstThunk : %08X\n",Imp.OriginalFirstThunk);
printf("TimeDateStamp : %08X\n",Imp.TimeDateStamp);
printf("ForwarderChain : %08X\n",Imp.ForwarderChain);
printf("Name : %08X----",Imp.Name);
SetFilePointer(hf,Imp.Name-(RAVOffset-PhOffset),0,FILE_BEGIN);
ReadFile(hf,&ch,1,&res,0);
while(ch)
{
printf("%c",ch);
ReadFile(hf,&ch,1,&res,0);
}
printf("\nFirstThunk : %08X\n",Imp.FirstThunk);
printf("Functions:\n");
if(Imp.OriginalFirstThunk)
{
PhThunk=Imp.OriginalFirstThunk-(RAVOffset-PhOffset);
}
else
{
PhThunk=Imp.FirstThunk-(RAVOffset-PhOffset);
}
Cnt1=0;
SetFilePointer(hf,PhThunk,0,FILE_BEGIN);
ReadFile(hf,&ThunkData,sizeof(IMAGE_THUNK_DATA),&res,0);
while(ThunkData.u1.Function)
{
if(ThunkData.u1.Function&IMAGE_ORDINAL_FLAG32)
{
printf("Ordinal : %04X\n",ThunkData.u1.Function&0xffff);
}
else
{
SetFilePointer(hf,ThunkData.u1.Function-(RAVOffset-PhOffset),0,FILE_BEGIN);
ReadFile(hf,&IName,sizeof(IMAGE_IMPORT_BY_NAME),&res,0);
printf("Hint : %04X----",IName.Hint);
SetFilePointer(hf,ThunkData.u1.Function-(RAVOffset-PhOffset)+2,0,FILE_BEGIN);
ReadFile(hf,&ch,1,&res,0);
while(ch)
{
printf("%c",ch);
ReadFile(hf,&ch,1,&res,0);
}
printf("\n");
}
Cnt1++;
SetFilePointer(hf,PhThunk+Cnt1*sizeof(IMAGE_THUNK_DATA),0,FILE_BEGIN);
ReadFile(hf,&ThunkData,sizeof(IMAGE_THUNK_DATA),&res,0);
}
printf("\n");
Cnt++;
SetFilePointer(hf,PhOffset+Cnt*sizeof(IMAGE_IMPORT_DESCRIPTOR),0,FILE_BEGIN);
ReadFile(hf,&Imp,sizeof(IMAGE_IMPORT_DESCRIPTOR),&res,0);
}
CloseHandle(hf);
return TRUE;
}
int main(int argc,char **argv)
{
IMAGE_NT_HEADERS NTHdr;
IMAGE_SECTION_HEADER SectionHdr[16];
DWORD V2P_Import;
DWORD RI,PI;
if(argc!=2)
{
printf("pe <filename>\n");
return 0;
}
if(DetectPe(argv[1],&NTHdr,SectionHdr))
{
printf("%s is a PE file,OK.\n",argv[1]);
}
else
{
printf("%s is Not a PE file.\n",argv[1]);
return 0;
}
OutputNTHdr(&NTHdr);
printf("\n");
OutputSectionHdr(SectionHdr,NTHdr.FileHeader.NumberOfSections);
printf("\n");
V2P_Import=LookforImportTable(&NTHdr,SectionHdr,RI,PI);
printf("Import Table\n");
printf("VirtualAddress : %08X\n",RI);
printf("PhysicalAddress : %08X\n",PI);
printf("VirtualAddress-PhysicalAddress : %08X\n",V2P_Import);
printf("\n");
ReadImportTable(argv[1],RI,PI);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -