鱼C论坛

 找回密码
 立即注册
查看: 2574|回复: 6

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

[复制链接]
发表于 2019-3-13 16:17:49 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
今天,老师演示了一段代码,来获取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;                                                                               
        }
代码是有些长,所以抱歉了,就是其中有些定义看不明白,以图片形式标记了,
求大哥能讲解一下,老师给的代码不懂得确实有些多?不好理解啊。谢谢了。。。
5.png
4.png
3.png
2.png
1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-3-13 16:19:15 | 显示全部楼层
图片顺序是1-5的顺序,本来是按顺序上传的,但是发表出来,结果给倒过来了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-3-13 16:20:29 | 显示全部楼层
老师秀代码把我秀的一头雾水,因为是网络听课,所以老师不讲解代码,导致没办法问老师,实在无奈啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-3-19 21:39:59 | 显示全部楼层
LPVOID是一个没有类型的指针,也就是说你可以将LPVOID类型的变量赋值给任意类型的指针,比如在参数传递时就可以把任意类型传递给一个LPVOID类型为参数的方法,然后在方法内再将这个“任意类型”从传递时的“LPVOID类型”转换回来
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

LPSTR被定义成是一个指向以NULL(‘\0’)结尾的32位ANSI字符数组指针
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-3-19 21:44:13 | 显示全部楼层
PWORD类型应该是word类型指针,*((PWORD)pFileBuffer 应该是把pFileBuffer强制转化成WORD类型指针然后取其中的值
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-3-19 21:47:37 | 显示全部楼层
我看你其余的不会的都是(XXX)xxx 之类的,这些是强制类型转换 括号里的是要转换成的类型(你用的这些都是宏定义后的类型),一般p开头的是指针类型。

我也是个新手,我的理解应该差不多了吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-3 12:34

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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