吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 7985|回复: 6
收起左侧

[C&C++ 原创] C++ 读取PE文件信息(读取PE导入表等)

[复制链接]
SuperProgram 发表于 2016-11-3 09:59
今天突然想自己实现一个PEID小工具,无奈颈椎不好啊,写好了核心代码只好匆匆结束了,不敢独享,拿出来与诸位朋友共勉了。
[C++] 纯文本查看 复制代码
// ReadPEInfo.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <Dbghelp.h>

void ReadNTPEInfo(PIMAGE_NT_HEADERS pImageNtPE);
ULONG RvaToOffset(IMAGE_NT_HEADERS * pNtHeader,ULONG Rva);

#define pNtHeaders pImageNtHeaders

int _tmain(int argc, _TCHAR* argv[])
{

	char file[]="win32.exe";

	//DOS头
	PIMAGE_DOS_HEADER pImageDosHeader;  
	//NT头(包括PE标识+Image_File_Header+OptionHeader)
    PIMAGE_NT_HEADERS pImageNtHeaders;  
	//标准PE头、
    PIMAGE_FILE_HEADER pImageFileHeader;  

	//扩展PE头
	IMAGE_OPTIONAL_HEADER32 pImageOptionHeaders;


    HANDLE hFile;  
    HANDLE hMapObject; 
	//DOS头
    PUCHAR uFileMap;

	hFile= CreateFile(file,GENERIC_READ,0,NULL,OPEN_EXISTING,0,0);
	if(hFile==NULL)
	{
		printf("打开文件失败\n");
		system("pause");
		return 0;
	}

	hMapObject=CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);
	if(hMapObject==NULL)
	{
		printf("创建文件映射内核对对象失败\n");
		system("pause");
		return 0;
	}

	//PE基址
	uFileMap=(PUCHAR)MapViewOfFile(hMapObject,FILE_MAP_READ,0,0,0);
	if(uFileMap==NULL)
	{
		printf("映射到进程地址空间失败\n");
		system("pause");
		return 0;
	}

	pImageDosHeader=(PIMAGE_DOS_HEADER)uFileMap;
	if(pImageDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
	{
		printf("不是PE结构\n");
		system("pause");
		return 0;
	}

	//定位到NT PE头
	pImageNtHeaders=(PIMAGE_NT_HEADERS)((PUCHAR)uFileMap+pImageDosHeader->e_lfanew);
	
	//导入表的相对虚拟地址(RVA)
    ULONG rva_ofimporttable=pImageNtHeaders->OptionalHeader.DataDirectory[1].VirtualAddress;
    //根据相对虚拟(rva)地址计算偏移地址(offset)
    ULONG offset_importtable=RvaToOffset(pImageNtHeaders,rva_ofimporttable);
    if(!offset_importtable)
	{
		printf("获取导入表偏移地址失败\n");
		system("pause");
		return 0;
	}

	PIMAGE_THUNK_DATA s;
    
    //取得导入表的地址
    IMAGE_IMPORT_DESCRIPTOR *pImportTable=(IMAGE_IMPORT_DESCRIPTOR *)((char*)uFileMap+offset_importtable);


	IMAGE_IMPORT_DESCRIPTOR null_iid;
    IMAGE_THUNK_DATA null_thunk;
    memset(&null_iid, 0, sizeof(null_iid));
    memset(&null_thunk, 0, sizeof(null_thunk));

	//每个元素代表了一个引入的DLL。
    for(int i=0; memcmp(pImportTable + i, &null_iid, sizeof(null_iid))!=0; i++)
    {
		char *dllName= (char*)(uFileMap+RvaToOffset(pImageNtHeaders,pImportTable[i].Name));

        //拿到了DLL的名字

        printf("模块[%d]: %s\n", i, (char*)dllName);
		PIMAGE_THUNK_DATA32 pThunk=(PIMAGE_THUNK_DATA32)(uFileMap+RvaToOffset(pImageNtHeaders,pImportTable[i].FirstThunk));
		
		while(pThunk->u1.Ordinal!=NULL)
		{
			PIMAGE_IMPORT_BY_NAME pname=(PIMAGE_IMPORT_BY_NAME)(uFileMap+RvaToOffset(pImageNtHeaders,pThunk->u1.AddressOfData));
			printf("函数编号: %d 名称: %s\n",pname->Hint,pname->Name);
			pThunk++;
		}
	}
	system("pause");
	return 0;
}


void ReadNTPEInfo(PIMAGE_NT_HEADERS pImageNtPE)
{
	printf("运行平台:   0x%04X\n",pImageNtPE->FileHeader.Machine);
	printf("节数量:   %d\n",pImageNtPE->FileHeader.NumberOfSections);
	printf("PE属性:   0x%04X\n",pImageNtPE->FileHeader.Characteristics);
}





//计算Offset
ULONG RvaToOffset(IMAGE_NT_HEADERS * pNtHeader,ULONG Rva)
{
	//PE节
    IMAGE_SECTION_HEADER *p_section_header;
    ULONG sNum,i;
    //取得节表项数目
    sNum=pNtHeader->FileHeader.NumberOfSections;
    //取得第一个节表项
    p_section_header=(IMAGE_SECTION_HEADER *)
                          ((BYTE *)pNtHeader+sizeof(IMAGE_NT_HEADERS));
    for(i=0;i<sNum;i++)
    {
		//printf("PE 节名称: %s\n",p_section_header->Name);
        if((p_section_header->VirtualAddress<=Rva)&&Rva<(p_section_header->VirtualAddress+p_section_header->SizeOfRawData))
		{
			return Rva-p_section_header->VirtualAddress+p_section_header->PointerToRawData;
		}	
        p_section_header++;    
    }
    return 0;
}


免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
dspowj + 1 + 1 编程风格挺赞,加油

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

StriveMario 发表于 2016-11-3 11:12
支持共享精神....
小虾米TC 发表于 2016-11-3 11:19
wanwanwanwan 发表于 2016-11-3 11:47
mihacker 发表于 2016-11-3 12:00
    后排支持下楼主  、
Nanson 发表于 2016-11-3 12:08
前排举爪支持,。
ynkyghty 发表于 2017-8-14 13:15

看上去不错的样子 支持 一下楼主
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-21 19:42

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表