A小小鸟 发表于 2019-3-13 16:17:49

关于代码中的一部分不理解,求指点一下

今天,老师演示了一段代码,来获取pe头文件的C语言程序,具体的源代码如下:
#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;                                                                               
        }
代码是有些长,所以抱歉了,就是其中有些定义看不明白,以图片形式标记了,
求大哥能讲解一下,老师给的代码不懂得确实有些多?不好理解啊。谢谢了。。。{:10_266:}

A小小鸟 发表于 2019-3-13 16:19:15

图片顺序是1-5的顺序,本来是按顺序上传的,但是发表出来,结果给倒过来了

A小小鸟 发表于 2019-3-13 16:20:29

老师秀代码把我秀的一头雾水,因为是网络听课,所以老师不讲解代码,导致没办法问老师,实在无奈啊

My_A 发表于 2019-3-19 21:39:59

LPVOID是一个没有类型的指针,也就是说你可以将LPVOID类型的变量赋值给任意类型的指针,比如在参数传递时就可以把任意类型传递给一个LPVOID类型为参数的方法,然后在方法内再将这个“任意类型”从传递时的“LPVOID类型”转换回来

My_A 发表于 2019-3-19 21:40:55

My_A 发表于 2019-3-19 21:39
LPVOID是一个没有类型的指针,也就是说你可以将LPVOID类型的变量赋值给任意类型的指针,比如在参数传递时就 ...

LPSTR被定义成是一个指向以NULL(‘\0’)结尾的32位ANSI字符数组指针

My_A 发表于 2019-3-19 21:44:13

PWORD类型应该是word类型指针,*((PWORD)pFileBuffer 应该是把pFileBuffer强制转化成WORD类型指针然后取其中的值

My_A 发表于 2019-3-19 21:47:37

我看你其余的不会的都是(XXX)xxx 之类的,这些是强制类型转换 括号里的是要转换成的类型(你用的这些都是宏定义后的类型),一般p开头的是指针类型。
{:9_235:}
我也是个新手,我的理解应该差不多了吧
页: [1]
查看完整版本: 关于代码中的一部分不理解,求指点一下