c语言,函数计算0869,【原创源码】【C/C++】32位PE文件信息查看器(WIN32控制台)...

[C++] 纯文本查看 复制代码#include

[i]#include

class PEFile

{

//转载请注明出处,本人不对引用此源码后程序产生的任何问题负责

public:

BYTE* p_buffer;///内容储存区

size_t size;///文件大小

DWORD headerOffset;///NT文件头地址

size_t GetFileSize(const char*filename)

{

HANDLE handle = CreateFile(filename, FILE_READ_EA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);

if (handle != INVALID_HANDLE_VALUE)

{

size_t size = ::GetFileSize(handle, NULL);

CloseHandle(handle);

return size;

}

return -1;

}

public:

BYTE GetBYTE(DWORD address)

{

return *((BYTE*)(p_buffer+address));

}

WORD GetWORD(DWORD address)

{

return *((WORD*)(p_buffer+address));

}

DWORD GetDWORD(DWORD address)

{

return *((DWORD*)(p_buffer+address));

}

PEFile()

{

p_buffer=nullptr;

size=0;

headerOffset=-1;

}

PEFile(const char*filename)

{

FILE* file=fopen(filename,"rb");

if(!file)

{

printf("读取失败");

exit(-1);

}

size=GetFileSize(filename);

p_buffer=new BYTE[size+1];

fread((void*)p_buffer,size+1,1,file);

fclose(file);

headerOffset=GetDWORD(0x3c);

}

PEFile(const PEFile& t)

{

size=t.size;

p_buffer=new BYTE[t.size+1];

headerOffset=t.headerOffset;

memcpy(p_buffer,t.p_buffer,size+1);

}

PEFile& operator = (const PEFile& t)

{

size=t.size;

if(p_buffer)

delete[] p_buffer;

p_buffer=new BYTE[t.size+1];

headerOffset=t.headerOffset;

memcpy(p_buffer,t.p_buffer,size+1);

}

bool LoadPEFile(const char* filename)

{

if(p_buffer)

delete[] p_buffer;

FILE* file=fopen(filename,"rb");

if(!file)return 0;

size=GetFileSize(filename);

p_buffer=new BYTE[size+1];

fread((void*)p_buffer,size+1,1,file);

fclose(file);

headerOffset=GetDWORD(0x3c);

return 1;

}

~PEFile()

{

delete[] p_buffer;

}

///导入表地址

IMAGE_DATA_DIRECTORY ImportDirectory()

{

return *(IMAGE_DATA_DIRECTORY*)(p_buffer+0x80+headerOffset);

}

///导出表地址

IMAGE_DATA_DIRECTORY ExportDirectory()

{

return *(IMAGE_DATA_DIRECTORY*)(p_buffer+0x78+headerOffset);

}

///获取第i个数据目录

IMAGE_DATA_DIRECTORY GetDataDirectory(WORD i)

{

return *(IMAGE_DATA_DIRECTORY*)(p_buffer+0x78+headerOffset+sizeof(IMAGE_DATA_DIRECTORY)*i);

}

///节区数量

WORD NumberOfSections()

{

return GetWORD(0x06+headerOffset);

}

///获取第i个节区头(从0开始计数)

IMAGE_SECTION_HEADER GetSectionHeader(WORD i)

{

DWORD sum=0;

sum+=sizeof(DWORD)+sizeof(IMAGE_FILE_HEADER)+GetNTFileHeader().SizeOfOptionalHeader;

sum+=i*sizeof(IMAGE_SECTION_HEADER);

IMAGE_SECTION_HEADER* ret=(IMAGE_SECTION_HEADER*)(p_buffer+headerOffset+sum);

return *ret;

}

///查询RVA所在节区

WORD SearchSectionOfRVA(DWORD RVA)

{

WORD sz=NumberOfSections();

for(WORD i=0;i

{

IMAGE_SECTION_HEADER cur=GetSectionHeader(i);

if(cur.VirtualAddress<=RVA&&cur.Misc.VirtualSize+cur.VirtualAddress>=RVA)

return i;

}

return -1;

}

///RVA转换为RAW

DWORD RVAtoRAW(DWORD RVA)

{

WORD loc=SearchSectionOfRVA(RVA);

if(loc==(WORD)-1)

return RVA;

IMAGE_SECTION_HEADER cur=GetSectionHeader(loc);

DWORD fileAlignment=GetDWORD(headerOffset+0x3c);

return RVA-cur.VirtualAddress+cur.PointerToRawData/fileAlignment*fileAlignment;

}

///获取导入描述表的数量

size_t GetImportDescriptorNums()

{

int ret=0;

DWORD p=ImportDirectory().VirtualAddress;

WORD inSection=SearchSectionOfRVA(p);///所在节区

p=RVAtoRAW(p);

IMAGE_SECTION_HEADER sec= GetSectionHeader(inSection);

DWORD p_end=sec.PointerToRawData+sec.SizeOfRawData;

while(1)

{

DWORD address=p+ret*sizeof(IMAGE_IMPORT_DESCRIPTOR);

IMAGE_IMPORT_DESCRIPTOR cur=*(IMAGE_IMPORT_DESCRIPTOR*)(p_buffer+address);

if( (!cur.OriginalFirstThunk && !cur.FirstThunk) || p_end

return ret;

else

++ret;

}

//return ret;

}

///获取第i张导入描述表

IMAGE_IMPORT_DESCRIPTOR GetImportDescriptor(int i)

{

return *(IMAGE_IMPORT_DESCRIPTOR*)(p_buffer+RVAtoRAW(ImportDirectory().VirtualAddress+i*sizeof(IMAGE_IMPORT_DESCRIPTOR)));

}

///获取第i张导入描述表的INT长度

size_t GetINTLength(WORD i)

{

IMAGE_IMPORT_DESCRIPTOR cur=GetImportDescriptor(i);

DWORD pINT=RVAtoRAW(cur.OriginalFirstThunk);

if(!pINT)return 0;

size_t ret=0;

while(GetDWORD(pINT+ret*sizeof(DWORD)))

++ret;

return ret;

}

///获取第i张导入描述表的第j个函数的函数名

BYTE* GetImprotFunctionName(int i,int j)

{

IMAGE_IMPORT_DESCRIPTOR cur=GetImportDescriptor(i);

DWORD pINT;

if(GetINTLength(i))

{

pINT=RVAtoRAW(cur.OriginalFirstThunk)+j*sizeof(DWORD);

DWORD p_func=RVAtoRAW(GetDWORD(pINT));

return p_buffer+p_func+sizeof(WORD);

}

else

{

DWORD address=GetImprotFunctionAddress(i,j);

address=RVAtoRAW(address);

return p_buffer+address+sizeof(WORD);

}

}

///获取第i张导入描述表的IAT长度

size_t GetIATLength(WORD i)

{

IMAGE_IMPORT_DESCRIPTOR cur=GetImportDescriptor(i);

DWORD pINT=RVAtoRAW(cur.FirstThunk);

if(!pINT)return 0;

size_t ret=0;

while(GetDWORD(pINT+ret*sizeof(DWORD)))

++ret;

return ret;

}

///获取第i张导入描述表的第j个函数的地址

DWORD GetImprotFunctionAddress(int i,int j)

{

IMAGE_IMPORT_DESCRIPTOR cur=GetImportDescriptor(i);

DWORD pIAT=RVAtoRAW(cur.FirstThunk)+j*sizeof(DWORD);

return GetDWORD(pIAT);

}

///获取导出表

IMAGE_EXPORT_DIRECTORY GetExportDirectory()

{

if(ExportDirectory().VirtualAddress!=NULL)

return *(IMAGE_EXPORT_DIRECTORY*)(p_buffer+RVAtoRAW(ExportDirectory().VirtualAddress));

else

{

IMAGE_EXPORT_DIRECTORY ret;

memset(&ret,0,sizeof(ret));

return ret;

}

}

///导出函数的个数

size_t GetExprotFunctionNums()

{

IMAGE_EXPORT_DIRECTORY cur=GetExportDirectory();

return cur.NumberOfFunctions;

}

///导出函数的具名函数个数

size_t GetExprotFunctionNameNums()

{

return GetExportDirectory().NumberOfNames;

}

///给出第i个导出函数的信息

char* GetExportMsg(WORD i,DWORD& address,DWORD& ordinal)

{

IMAGE_EXPORT_DIRECTORY cur=GetExportDirectory();

if(cur.AddressOfFunctions!=0)

address=GetDWORD(RVAtoRAW(cur.AddressOfFunctions)+i*sizeof(DWORD));

else

address=0;

if(cur.AddressOfNameOrdinals!=0)

ordinal=GetWORD(RVAtoRAW(cur.AddressOfNameOrdinals)+i*sizeof(WORD));

else

ordinal=0;

if(cur.Name!=0)

{

DWORD p_name=GetDWORD(RVAtoRAW(cur.AddressOfNames)+i*sizeof(DWORD));

return (char*)(p_buffer+RVAtoRAW(p_name));

}

else

return nullptr;

}

///获取DOS头

IMAGE_DOS_HEADER GetDosHeader()

{

return *(IMAGE_DOS_HEADER*)p_buffer;

}

///获取NT文件头

IMAGE_FILE_HEADER GetNTFileHeader()

{

return *(IMAGE_FILE_HEADER*)(p_buffer+headerOffset+sizeof(DWORD));

}

///获取NT可选头

IMAGE_OPTIONAL_HEADER32 GetNTOptionalHeader()

{

return *(IMAGE_OPTIONAL_HEADER32*)(p_buffer+headerOffset+0x18);

}

///获取从定向表

IMAGE_BASE_RELOCATION GetRelocation(WORD* &reloctionTable)

{

if(!HasDataDirectory(5))

{

reloctionTable=nullptr;

IMAGE_BASE_RELOCATION ret;

memset(&ret,0,sizeof(IMAGE_BASE_RELOCATION));

return ret;

}

DWORD p_rel=RVAtoRAW(GetDataDirectory(5).VirtualAddress);

reloctionTable=(WORD*)(p_buffer+p_rel+sizeof(IMAGE_BASE_RELOCATION));

return *(IMAGE_BASE_RELOCATION*)(p_buffer+p_rel);

}

///获取从定向表

IMAGE_BASE_RELOCATION GetRelocation()

{

DWORD p_rel=RVAtoRAW(GetDataDirectory(5).VirtualAddress);

if(!p_rel)

{

IMAGE_BASE_RELOCATION ret;

memset(&ret,0,sizeof(IMAGE_BASE_RELOCATION));

return ret;

}

return *(IMAGE_BASE_RELOCATION*)(p_buffer+RVAtoRAW(GetDataDirectory(5).VirtualAddress));

}

///检查是否存在数据目录的第i项

bool HasDataDirectory(WORD i)

{

return GetDataDirectory(i).VirtualAddress;

}

};

PEFile pe;

FILE* outfile;

///对应-q

void ExitProgram()

{

if(outfile)

fclose(outfile);

exit(0);

}

///对应-l

void LoadPEFile(const char*filename)

{

if(!pe.LoadPEFile(filename))

printf("文件不存在或无法读取\n");

else

printf("读取成功\n");

}

///对应-f filename

void PrintInFile(const char*filename)

{

outfile=fopen(filename,"w");

}

void PrintMsg(char*str)

{

if(outfile)

fprintf(outfile,"%s",str);

printf("%s",str);

}

///对应于-m dos [main]

void MsgOfDos(bool isMain)

{

IMAGE_DOS_HEADER dosHeader=pe.GetDosHeader();

char str[10000];

strcpy(str,"\n----------------------------DOS头信息--------------------------------\n\n");

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","DOS文件标记(Magic DOS signature)",dosHeader.e_magic);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","重定位表的文件地址(File Address of relocation table)",dosHeader.e_lfarlc);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","NT头地址(Offset to start of PE header)",dosHeader.e_lfanew);

PrintMsg(str);

if(!isMain)

{

sprintf(str,"%-55s:0x%04x\n","最后一页大小(Bytes on last page of file)",dosHeader.e_cblp);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x (%d)\n","文件页数(Pages in file)",dosHeader.e_cp,dosHeader.e_cp);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","文件迁移(Relocations)",dosHeader.e_crlc);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","头的段大小(Size of header in paragraphs)",dosHeader.e_cparhdr);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","最小额外段需求(Minimun extra paragraphs needs)",dosHeader.e_minalloc);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","最大额外段需求(Maximun extra paragraphs needs)",dosHeader.e_maxalloc);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","DOS代码的初始化堆栈SS(intial(relative)SS value)",dosHeader.e_ss);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","DOS代码的初始化堆栈指针SP(intial SP value)",dosHeader.e_sp);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","校验和(Checksum)",dosHeader.e_csum);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","DOS代码的初始化指令入口[指针IP](intial IP value)",dosHeader.e_ip);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","DOS代码的初始堆栈入口(intial(relative)CS value)",dosHeader.e_cs);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","Overlay number",dosHeader.e_ovno);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","OEM identifier(for e_oeminfo)",dosHeader.e_oemid);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","OEM information;e_oemid specific",dosHeader.e_oeminfo);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x 0x%04x 0x%04x 0x%04x\n","保留字(Reserved words,[e_res])",

dosHeader.e_res[0],

dosHeader.e_res[1],

dosHeader.e_res[2],

dosHeader.e_res[3]);

PrintMsg(str);

sprintf(str,"%-55s:\n0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n","保留字2(Reserved words,[e_res2])",

dosHeader.e_res2[0],

dosHeader.e_res2[1],

dosHeader.e_res2[2],

dosHeader.e_res2[3],

dosHeader.e_res2[4],

dosHeader.e_res2[5],

dosHeader.e_res2[6],

dosHeader.e_res2[7],

dosHeader.e_res2[8],

dosHeader.e_res2[9]);

PrintMsg(str);

}

strcpy(str,"\n--------------------------DOS头信息-结束-------------------------------\n\n");

PrintMsg(str);

}

///对应于-m ntfh [main]

void MsgOfNtfh(bool isMain)

{

IMAGE_FILE_HEADER ntfh=pe.GetNTFileHeader();

char str[10000];

strcpy(str,"\n----------------------------NT文件头信息--------------------------------\n\n");

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","CPU机器码(Machine)",ntfh.Machine);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x(%d)\n","节区数量(NumberOfSections)",ntfh.NumberOfSections,ntfh.NumberOfSections);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","属性(Characteristics)",ntfh.Characteristics);

PrintMsg(str);

if(!isMain)

{

sprintf(str,"%-55s:0x%08x\n","时间戳(TimeDateStamp)",ntfh.TimeDateStamp);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","符号表指针(PointerToSymbolTable)",ntfh.PointerToSymbolTable);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","符号表大小(NumberOfSymbols)",ntfh.NumberOfSymbols);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","可选头大小(SizeOfOptionalHeader)",ntfh.SizeOfOptionalHeader);

PrintMsg(str);

}

strcpy(str,"\n--------------------------DNT文件头信息-结束-------------------------------\n\n");

PrintMsg(str);

}

///对应于-m ntoh [main] [d]

void MsgOfNtoh(bool isMain,bool isD)

{

IMAGE_OPTIONAL_HEADER32 ntoh=pe.GetNTOptionalHeader();

char str[10000];

strcpy(str,"\n----------------------------NT可选头信息--------------------------------\n\n");

PrintMsg(str);

sprintf(str,"%-55s:0x%04x(%d位)\n","可选头类型(Magic)",ntoh.Magic,ntoh.Magic==0x10b?32:64);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","EP地址[RVA](AddressOfEntryPoint)",ntoh.AddressOfEntryPoint);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","映象基址(ImageBase)",ntoh.ImageBase);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","节对齐(SectionAlignment)",ntoh.SectionAlignment);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","文件节对齐(FileAlignment)",ntoh.FileAlignment);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","映象大小(SizeOfImage)",ntoh.SizeOfImage);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","PE头大小(SizeOfHeaders)",ntoh.SizeOfHeaders);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x(%s)\n","子系统(Subsystem)",ntoh.Subsystem,ntoh.Subsystem==1?"系统驱动":

ntoh.Subsystem==2?"窗口应用程序":"控制台应用程序");

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","数据目录项数(NumberOfRvaAndSizes)",ntoh.NumberOfRvaAndSizes);

PrintMsg(str);

if(!isMain)

{

sprintf(str,"%-55s:0x%02x\n","连接器版本号(MajorLinkerVersion)",ntoh.MajorLinkerVersion);

PrintMsg(str);

sprintf(str,"%-55s:0x%02x\n","连接器版本号(MinorLinkerVersion)",ntoh.MinorLinkerVersion);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","代码段长度(SizeOfCode)",ntoh.SizeOfCode);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","初始化数据长度(SizeOfInitializedData)",ntoh.SizeOfInitializedData);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","未初始化的数据长度(SizeOfUninitializedData)",ntoh.SizeOfUninitializedData);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","代码段起始地址的RVA(BaseOfCode)",ntoh.BaseOfCode);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","数据段起始地址的RVA(BaseOfData)",ntoh.BaseOfData);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","操作系统版本号(MajorOperatingSystemVersion)",ntoh.MajorOperatingSystemVersion);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","操作系统版本号(MinorOperatingSystemVersion)",ntoh.MinorOperatingSystemVersion);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","映象的版本号(MajorImageVersion)",ntoh.MajorImageVersion);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","映象的版本号(MinorImageVersion)",ntoh.MinorImageVersion);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","所需子系统版本号(MajorSubsystemVersion)",ntoh.MajorSubsystemVersion);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","所需子系统版本号(MinorSubsystemVersion)",ntoh.MinorSubsystemVersion);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","WIN32版本值(Win32VersionValue)",ntoh.Win32VersionValue);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","映象文件校验和(CheckSum)",ntoh.CheckSum);

PrintMsg(str);

sprintf(str,"%-55s:0x%04x\n","DLL的文件属性(DllCharacteristics)",ntoh.DllCharacteristics);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","栈保留内存(SizeOfStackReserve)",ntoh.SizeOfStackReserve);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","栈初始占用内存(SizeOfStackCommit)",ntoh.SizeOfStackCommit);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","堆保留内存(SizeOfHeapReserve)",ntoh.SizeOfHeapReserve);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","堆初始占用内存(SizeOfHeapReserve)",ntoh.SizeOfHeapCommit);

PrintMsg(str);

sprintf(str,"%-55s:0x%08x\n","LoaderFlags",ntoh.LoaderFlags);

PrintMsg(str);

}

if(isD)

{

strcpy(str,"\n---------------------数据目录---------------------\n\n");

PrintMsg(str);

char* DataDirectory[50]=

{"Export Directory"

,"Import Directory"

,"Resource Directory"

,"Exception Directory"

,"Security Directory"

,"Base Relocation Table"

,"Debug Directory"

,"COPYRIGHT/Architecture Specific Data"

,"RVA of GLOBALPTR"

,"TLS Directory"

,"Load Configuration Directory"

,"Bound Import Directory in headers"

,"Import Address Table"

,"Delay Load Import Descriptors"

,"COM Runtime descriptor"

,"Reserved Directory"

};

sprintf(str,"%-50s%-8s%7s%-8s\n","名称","地址","","大小");

PrintMsg(str);

for(DWORD i=0;i

{

IMAGE_DATA_DIRECTORY cur=pe.GetDataDirectory(i);

sprintf(str,"%-50s0x%08x%5s0x%08x\n",DataDirectory[i],cur.VirtualAddress,"",cur.Size);

PrintMsg(str);

}

strcpy(str,"\n-------------------数据目录-结束------------------\n\n");

PrintMsg(str);

}

strcpy(str,"\n-------------------------NT可选头信息-结束------------------------------\n\n");

PrintMsg(str);

}

///对应-i [i][j]

void MsgOfImport(int i,int j,bool isSingle=1)

{

char str[10000];

if(isSingle)

{

sprintf(str,"%s.%s( address/ordinal= 0x%08x)\n",

pe.RVAtoRAW(pe.GetImportDescriptor(i).Name)+pe.p_buffer,

pe.GetImprotFunctionName(i,j),

pe.GetImprotFunctionAddress(i,j)

);

}

else

{

sprintf(str,"%s.%s",

pe.RVAtoRAW(pe.GetImportDescriptor(i).Name)+pe.p_buffer,

pe.GetImprotFunctionName(i,j)

);

for(int i=0;str[i];i++)

if(str[i]<0)

{

strcpy(str,"未知的函数名,请通过序号/地址识别函数");

break;

}

sprintf(str,"%-50s0x%08x\n",

str,

pe.GetImprotFunctionAddress(i,j)

);

}

PrintMsg(str);

}

void MsgOfImport(int i)

{

char str[10000];

IMAGE_IMPORT_DESCRIPTOR cur=pe.GetImportDescriptor(i);

sprintf(str,"库名:%-50s\n", pe.RVAtoRAW(cur.Name)+pe.p_buffer);

PrintMsg(str);

size_t l_int=pe.GetINTLength(i),l_iat=pe.GetIATLength(i);

sprintf(str,"INT长度:0x%08x(%d),IAT长度:0x%08x(%d)\n\n",l_int,l_int,l_iat,l_iat);

PrintMsg(str);

sprintf(str,"%-50s%-08s\n","函数名","地址/编号");

PrintMsg(str);

for(int j=0;j

MsgOfImport(i,j,0);

}

void MsgOfImport()

{

if(!pe.HasDataDirectory(1))

{

PrintMsg("该PE文件不存在导入表!\n");

return ;

}

int sz=pe.GetImportDescriptorNums();

char str[10000];

sprintf(str,"导入表数量:%d\n\n",sz);

PrintMsg(str);

for(int i=0;i

{

MsgOfImport(i);

PrintMsg("\n\n");

}

}

///对应-e [i]

void MsgOfExport(int i,bool isSingle=1)

{

char str[10000];

DWORD address,ordinal;

char* name=pe.GetExportMsg(i,address,ordinal);

if(isSingle)

{

sprintf(str,"%s( address = 0x%08x , ordinal = 0x%08x (%d) )\n",name?name:"无法识别的函数名/函数不存在",address,ordinal,ordinal);

PrintMsg(str);

}

else

{

sprintf(str,"%-50s0x%08x%10s0x%08x (%d)\n",name?name:"无法识别的函数名/函数不存在",address,"",ordinal,ordinal);

PrintMsg(str);

}

}

void MsgOfExport()

{

size_t sz=pe.GetExprotFunctionNums();

if(sz==0)

PrintMsg("该PE文件不存在EAT!\n");

else

{

for(int i=0;i

MsgOfExport(i,0);

}

}

///对应-s [i]

void MsgOfSection(int i)

{

IMAGE_SECTION_HEADER cur=pe.GetSectionHeader(i);

char str[10000];

PrintMsg("\n\n");

char temp[10];

for(int i=0;i<9&&cur.Name[i];i++)

temp[i]=cur.Name[i];

temp[9]=0;

sprintf(str,"%-50s: %s\n","节区名(Name)",temp);

PrintMsg(str);

sprintf(str,"%-50s: 0x%08x\n","节区大小(VirtualSize)/物理地址(PhysicalAddress)",cur.Misc.VirtualSize);

PrintMsg(str);

sprintf(str,"%-50s: 0x%08x\n","节区RVA(VirtualAddress)",cur.VirtualAddress);

PrintMsg(str);

sprintf(str,"%-50s: 0x%08x\n","文件对齐尺寸(SizeOfRawData)",cur.SizeOfRawData);

PrintMsg(str);

sprintf(str,"%-50s: 0x%08x\n","文件偏移(PointerToRawData)",cur.PointerToRawData);

PrintMsg(str);

sprintf(str,"%-50s: 0x%08x\n","重定位偏移(PointerToRelocations)",cur.PointerToRelocations);

PrintMsg(str);

sprintf(str,"%-50s: 0x%08x\n","行号表偏移(PointerToLinenumbers)",cur.PointerToLinenumbers);

PrintMsg(str);

sprintf(str,"%-50s: 0x%04x\n","重定位数目(NumberOfRelocations)",cur.NumberOfRelocations);

PrintMsg(str);

sprintf(str,"%-50s: 0x%04x\n","行号表数目(NumberOfLinenumbers)",cur.NumberOfLinenumbers);

PrintMsg(str);

sprintf(str,"%-50s: 0x%08x\n","属性(Characteristics)",cur.Characteristics);

PrintMsg(str);

PrintMsg("\n\n");

}

void MsgOfSection()

{

int sz=pe.NumberOfSections();

char str[10000];

sprintf(str,"节区数量:%d\n\n",sz);

PrintMsg(str);

for(int i=0;i

MsgOfSection(i);

}

///对应-r [i]

void MsgOfRelocation(int i,bool isSingle=1)

{

WORD *p_loc;

DWORD va;

va=pe.GetRelocation(p_loc).VirtualAddress;

p_loc+=i*sizeof(WORD);

WORD type=((*p_loc)&0xf000)>>12;

WORD val=(*p_loc)&0x0fff;

//printf("0x%04x%20s0x%04x%20s0x%08x\n",val,"",type,"",va+val);

char str[10000];

if(isSingle)

{

sprintf(str,"偏移=0x%04x,类型=0x%04x,编码地址=0x%08x\n",val,type,va+val);

}

else

{

sprintf(str,"0x%04x%20s0x%04x%20s0x%08x\n",val,"",type,"",va+val);

}

PrintMsg(str);

}

void MsgOfRelocation()

{

if(!pe.HasDataDirectory(5))

{

PrintMsg("该PE文件不存在PE重定向表!\n");

return ;

}

int sz=pe.GetRelocation().SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION);

char str[10000];

sprintf(str,"重定向表长度:%d\n%-4s%22s%-4s%22s%-4s\n",sz,"偏移","","类型","","编码地址");

PrintMsg(str);

for(int i=0;i

MsgOfRelocation(i,0);

}

///对应-h/-?

void PrintHelp()

{

puts("---------------------------------------------------------------------");

puts("-h/-? 查看帮助");

puts("-q 退出程序");

puts("-l filenname 打开名为filename的PE文件");

puts("-f filename 从当前操作起把输出写在文件中(原文件(如果存在)内容会被覆盖)");

puts("-m dos/ntfh/ntoh [main] [d] 显示DOS头/NT文件头/NT可选头信息,main参数:只显示主要信息.d:显示NT可选头的地址数据目录");

puts("-i [i][j] 第i个导入库的第j个导入函数信息,不填写则显示全部");

puts("-e [i] 第i个导出函数信息,不填写则显示全部");

puts("-s [i] 显示第i个节区信息,不填写则显示全部");

puts("-r [i] 显示第i个重定向信息,不填写则显示全部");

puts("-c RVA RVA转为RAW,RVA:要转换的RVA地址(16进制)");

puts("-cls 清屏");

puts("---------------------------------------------------------------------");

}

#include

#include

using namespace std;

struct OpQueue:public queue

{

string front()

{

if(empty())

return string("");

return queue::front();

}

};

void RunOpList(OpQueue& opList)

{

opList.push(string(""));

while(!opList.empty())

{

string cur=opList.front();

opList.pop();

if(cur=="-l")

{

cur=opList.front();

opList.pop();

LoadPEFile(cur.c_str());

}

if(cur=="-cls")

{

system("cls");

}

else if(cur=="-q")

{

ExitProgram();

}

else if(cur=="-h"||cur=="-?")

{

PrintHelp();

}

else if(cur=="-f")

{

cur=opList.front();

opList.pop();

PrintInFile(cur.c_str());

}

else if(cur=="-m")

{

cur=opList.front();

opList.pop();

if(cur=="dos")

{

cur=opList.front();

if(cur=="main")

{

opList.pop();

MsgOfDos(1);

}

else

MsgOfDos(0);

}

else if(cur=="ntfh")

{

cur=opList.front();

if(cur=="main")

{

opList.pop();

MsgOfNtfh(1);

}

else

MsgOfNtfh(0);

}

else if(cur=="ntoh")

{

cur=opList.front();

bool isMain=0,isD=0;

if(cur=="main")

{

opList.pop();

isMain=1;

}

cur=opList.front();

if(cur=="d")

{

opList.pop();

isD=1;

}

MsgOfNtoh(isMain,isD);

}

else

{

puts("命令错误");

return;

}

}

else if(cur=="-i")

{

cur=opList.front();

int i=-1,j=-1;

if(cur[0]!='-'&&cur!="")

{

opList.pop();

sscanf(cur.c_str(),"%d",&i);

}

cur=opList.front();

if(cur[0]!='-'&&cur!="")

{

opList.pop();

sscanf(cur.c_str(),"%d",&j);

}

if(i!=-1&&j!=-1)

MsgOfImport(i,j);

else if(i!=-1&&j==-1)

MsgOfImport(i);

else

MsgOfImport();

}

else if(cur=="-e")

{

cur=opList.front();

int i=-1;

if(cur[0]!='-'&&cur[0])

{

opList.pop();

sscanf(cur.c_str(),"%d",&i);

}

if(i==-1)

MsgOfExport();

else

MsgOfExport(i);

}

else if(cur=="-s")

{

cur=opList.front();

int i=-1;

if(cur[0]!='-'&&cur[0])

{

opList.pop();

sscanf(cur.c_str(),"%d",&i);

}

if(i==-1)

MsgOfSection();

else

MsgOfSection(i);

}

else if(cur=="-r")

{

cur=opList.front();

int i=-1;

if(cur[0]!='-'&&cur[0])

{

opList.pop();

sscanf(cur.c_str(),"%d",&i);

}

if(i==-1)

MsgOfRelocation();

else

MsgOfRelocation(i);

}

else if(cur=="-c")

{

cur=opList.front();

int i=-1;

if(cur[0]!='-'&&cur[0])

{

opList.pop();

sscanf(cur.c_str(),"%x",&i);

}

if(i==-1)

printf("指令错误\n");

else

{

i=pe.RVAtoRAW(i);

char ch[20];

sprintf(ch,"0x%08x\n",i);

PrintMsg(ch);

}

}

}

}

void GetOpList(OpQueue& opList)

{

opList=OpQueue();

char str[10000];

char *p=str;

gets(str);

for(int i=0;p[i];i++)

{

if(p[i]=='\t'||p[i]=='\n'||p[i]=='\r'||p[i]==' ')

{

p[i]=0;

if(*p)

{

opList.push(string(p));

p+=i+1;

}

i=0;

}

}

if(*p)

{

opList.push(string(p));

}

}

int main(int argc,char** argv)

{

puts(" ");

puts("----------------------PE解析器V1.0 by lc思念落叶----------------------");

puts(" ");

puts(" ");

if(argc==1)

{

while(!pe.p_buffer)

{

OpQueue opList;

printf("请使用-l filename指令读取PE文件\n");

GetOpList(opList);

RunOpList(opList);

}

PrintHelp();

}

else if(argc>1)

{

OpQueue opList;

int loc=1;

if(argv[1][0]!='-')

LoadPEFile(argv[loc++]);

for(int i=loc;i

opList.push(string(argv[i]));

RunOpList(opList);

}

while(1)

{

OpQueue opList;

GetOpList(opList);

puts("---------------------------------------------------------------------");

RunOpList(opList);

}

}

[i]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值