// win原理Day001.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
//1 把文件读到内存中
char* ReadFileToMemory(char* pFilePath)
{
//1 获取文件句柄
HANDLE hFile = CreateFileA(pFilePath,
GENERIC_READ | GENERIC_WRITE,
FALSE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("文件打开失败\n");
return 0;
}
//2.获取文件大小
DWORD dwFileSize = GetFileSize(hFile, NULL);
//3.申请内存空间
char* pBuf = new char[dwFileSize]{};
if (!pBuf)
{
CloseHandle(hFile);
printf("内存申请失败\n");
return 0;
}
//4.读取文件内容到内存空间
DWORD dwRead;
ReadFile(hFile, pBuf, dwFileSize, &dwRead, NULL);
//5. 返回内存地址
return pBuf;
}
//2 是否是PE文件
bool IsPeFile(char* pBuf)
{
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pBuf;
if (pDos->e_magic != IMAGE_DOS_SIGNATURE)
{
printf("不是PE文件\n");
return false;
}
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)
(pDos->e_lfanew + pBuf);
if (pNt->Signature != IMAGE_NT_SIGNATURE)
{
printf("不是PE文件\n");
return false;
}
return true;
}
//3 解析PE(头部重要字段)
void ShowImportantHead(char* pBuf)
{
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pBuf;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + pBuf);
//文件默认加载基址
printf("默认加载基址:0x%08X\n", pNt->OptionalHeader.ImageBase);
//文件入口点
printf("文件入口点:0x%08X\n", pNt->OptionalHeader.AddressOfEntryPoint);
//文件区段个数
printf("文件区段个数:%d\n", pNt->FileHeader.NumberOfSections);
//。。。
}
int _tmain(int argc, _TCHAR* argv[])
{
char* pBuf = ReadFileToMemory("123.exe");
if (IsPeFile(pBuf))
{
ShowImportantHead(pBuf);
}
delete pBuf;
return 0;
}