首页
社区
课程
招聘
未解决 [求助]关于pe解析中有点不理解
发表于: 2020-2-12 16:50 2203

未解决 [求助]关于pe解析中有点不理解

2020-2-12 16:50
2203
学习pe查找头文件,网上看了一个示例代码:功能是查找pe的各个头文件
代码如下:
#include "stdafx.h"                                                                                       
#include<windows.h>                                                                                       
#include <stdlib.h>                                                                                       
LPVOID ReadPEFile(LPSTR lpszFile)                                                                       
                {                                                                               
                        FILE *pFile = NULL;                                                                       
                        DWORD fileSize = 0;                                                                       
                        LPVOID pFileBuffer = NULL;                                                                       

                        //打开文件                                                                       
                        pFile = fopen(lpszFile, "rb");                                                                       
                        if(!pFile)                                                                       
                        {                                                                       
                                printf(" 无法打开 EXE 文件! ");                                                               
                                return NULL;                                                               
                        }                                                                       
                        //读取文件大小                                                                       
                        fseek(pFile, 0, SEEK_END);                                                                       
                        fileSize = ftell(pFile);                                                                       
                        fseek(pFile, 0, SEEK_SET);                                                                       
                        //分配缓冲区                                                                       
                        pFileBuffer = malloc(fileSize);                                                                       

                        if(!pFileBuffer)                                                                       
                        {                                                                       
                                printf(" 分配空间失败! ");                                                               
                                fclose(pFile);                                                               
                                return NULL;                                                               
                        }                                                                       
                        //将文件数据读取到缓冲区                                                                       
                        size_t n = fread(pFileBuffer, fileSize, 1, pFile);                                                                       
                        if(!n)                                                                       
                        {                                                                       
                                printf(" 读取数据失败! ");                                                               
                                free(pFileBuffer);                                                               
                                fclose(pFile);                                                               
                                return NULL;                                                               
                        }                                                                       
                        //关闭文件                                                                       
                        fclose(pFile);                                                                       
                        return pFileBuffer;                                                                       
                }                                                                               

                void PrintNTHeaders()                                                                               
                {                                                                               
                        LPVOID pFileBuffer = NULL;                                                                       
                        PIMAGE_DOS_HEADER pDosHeader = NULL;                                                                       
                        PIMAGE_NT_HEADERS pNTHeader = NULL;                                                                       
                        PIMAGE_FILE_HEADER pPEHeader = NULL;                                                                       
                        PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;                                                                       
                        PIMAGE_SECTION_HEADER pSectionHeader = NULL;                                                                       

                        pFileBuffer = ReadPEFile("c:\\ipmsg.exe");                                                                       
                        if(!pFileBuffer)                                                                       
                        {                                                                       
                                printf("文件读取失败\n");                                                               
                                return ;                                                                
                        }                                                                       

                        //判断是否是有效的MZ标志                                                                       
                        if(*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE)                                                                       
                        {                                                                       
                                printf("不是有效的MZ标志\n");                                                               
                                free(pFileBuffer);                                                               
                                return ;                                                                
                        }                                                                       
                        pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;                                                                       
                        //打印DOC头                                                                       
                        printf("********************DOC头********************\n");                                                                       
                        printf("MZ标志:%x\n",pDosHeader->e_magic);                                                                       
                        printf("PE偏移:%x\n",pDosHeader->e_lfanew);                                                                       
                        //判断是否是有效的PE标志                                                                       
                        if(*((PDWORD)((DWORD)pFileBuffer+pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)                                                                       
                        {                                                                       
                                printf("不是有效的PE标志\n");                                                               
                                free(pFileBuffer);                                                               
                                return ;                                                               
                        }                                                                       
                        pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);                                                                       
                        //打印NT头                                                                       
                        printf("********************NT头********************\n");                                                                       
                        printf("NT:%x\n",pNTHeader->Signature);                                                                       
                        pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 4);                                                                       
                        printf("********************PE头********************\n");                                                                       
                        printf("PE:%x\n",pPEHeader->Machine);                                                                       
                        printf("节的数量:%x\n",pPEHeader->NumberOfSections);                                                                       
                        printf("SizeOfOptionalHeader:%x\n",pPEHeader->SizeOfOptionalHeader);                                                                       
                        //可选PE头                                                                       
                        pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);                                                                       
                        printf("********************OPTIOIN_PE头********************\n");                                                                       
                        printf("OPTION_PE:%x\n",pOptionHeader->Magic);                                                                       
                        //释放内存                                                                       
                        free(pFileBuffer);                                                                       
                }                                                                               
        int main(int argc, char* argv[])                                                                                       
        {                                                                                       
                ReadPEFile("c:\\ipmsg.exe");                                                                               
                PrintNTHeaders();                                                                               
                return 0;      
主要是看不懂这几行代码
//判断是否是有效的PE标志                                                                       
                        if(*((PDWORD)((DWORD)pFileBuffer+pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)                                                                       
                        {                                                                       
                                printf("不是有效的PE标志\n");                                                               
                                free(pFileBuffer);                                                               
                                return ;                                                               
                        }                                                                       
                        pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);   
我不明白  pFileBuffer是一个void的指针类型,为什么前面能加上DWORD,指针类型转化成DWORD,为什么编译器不报错误啊?这是什么原理啊??意义在哪里啊??
                 

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 7130
活跃值: (3778)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
以前强转就是这样的,现在可以reinterpret_cast<>了
2020-2-12 18:07
0
雪    币: 1931
活跃值: (442)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
c语言指针类型强转没毛病啊, 原理?你写编译器就可以限制他不能强制转换喽,非得报错嘛,你知道底层怎么转换不就行了, 意义?更方便的操作内存啊
2020-2-12 20:53
0
雪    币: 2510
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
帮顶
2020-2-13 01:00
0
游客
登录 | 注册 方可回帖
返回
//