zoukankan      html  css  js  c++  java
  • PE解析到区段表

    // PE001.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include<windows.h>
    #include<time.h>
    
    
    //函数声明,转换文件偏移量
    DWORD CalcOffect(DWORD Rva);
    
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    
        //删除文件
        //DeleteFile(TEXT("D:\Test.txt"));
        //拷贝文件,同时也可以改名字
        //CopyFile(TEXT("D:\Test.txt"), TEXT("D:\123\Testhehe.txt"),TRUE);
        //移动文件,同时也可以改名字
        //MoveFile(TEXT("D:\Test.txt"), TEXT("D:\123\Testheihei.txt"));
    
        //设置文件指针,这个函数需要注意一下。
        //SetFilePointer()
    
        //得到文件的句柄
        HANDLE hFile = CreateFile(
            TEXT("D:\5.exe"),
            GENERIC_READ | GENERIC_WRITE,
            0,
            NULL,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            NULL
            );
        //获得文件大小
        DWORD dwFileSize = GetFileSize(hFile, NULL);
        char *pFile = new char[dwFileSize];
        DWORD dwRubbish = 0;
        //将文件内容读取到开辟的空间中
        ReadFile(hFile, pFile, dwFileSize, &dwRubbish, NULL);
        if (((PIMAGE_DOS_HEADER)pFile)->e_magic != IMAGE_DOS_SIGNATURE)
        {
            //不是DOS头,返回
            return -1;
        }
        //将文件偏移值取出,保存
        DWORD dwNewPos = (DWORD)pFile + ((PIMAGE_DOS_HEADER)pFile)->e_lfanew;
        //将地址转换为NT头指针
        PIMAGE_NT_HEADERS32 pNTHeader = (PIMAGE_NT_HEADERS32)(dwNewPos);
        if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
        {
            //不是NT头,说明不是PE文件,返回
            return -1;
        }
        //取出NT头文件中成员
        PIMAGE_FILE_HEADER         pFileHeader = &(pNTHeader->FileHeader);
        
        //打印出头文件中结构体成员
        printf("文件运行平台:    %x
    ", pFileHeader->Machine);
        printf("区段的数量:      %x
    ", pFileHeader->NumberOfSections);
        printf("文件创建时间:    %x
    ", pFileHeader->TimeDateStamp);
        printf("符号表偏移:      %x
    ", pFileHeader->PointerToSymbolTable);
        printf("符号个数:        %x
    ", pFileHeader->NumberOfSymbols);
        printf("扩展头大小:      %x
    ", pFileHeader->SizeOfOptionalHeader);
        printf("PE文件的一些属性:%x
    
    ", pFileHeader->Characteristics);
        //转换时间  tm *FIleTime = gmtime((time_t *)pFileHeader->TimeDateStamp);
        //扩展头信息打印
        PIMAGE_OPTIONAL_HEADER32   pOptionalHeader = &(pNTHeader->OptionalHeader);
        printf("魔数:                       %x
    ", pOptionalHeader->Magic);
        printf("所有代码区段的总大小:       %x
    ", pOptionalHeader->SizeOfCode);
        printf("已初始化数据总大小:         %x
    ", pOptionalHeader->SizeOfInitializedData);
        printf("未初始化数据总大小:         %x
    ", pOptionalHeader->SizeOfUninitializedData);
        printf("程序开始执行的相对虚拟地址: %x
    ", pOptionalHeader->AddressOfEntryPoint);
        printf("起始代码的相对虚拟地址:     %x
    ", pOptionalHeader->BaseOfCode);
        printf("起始数据的相对虚拟地址:     %x
    ", pOptionalHeader->BaseOfData);
        printf("默认加载基址:               %x
    ", pOptionalHeader->ImageBase);
        printf("块对齐数:                   %x
    ", pOptionalHeader->SectionAlignment);
        printf("文件对齐数:                 %x
    ", pOptionalHeader->FileAlignment);
        printf("内存大小:                   %x
    ", pOptionalHeader->SizeOfImage);
        printf("文件起始偏移:               %x
    ", pOptionalHeader->SizeOfHeaders);
        printf("子系统:                     %x
    ", pOptionalHeader->Subsystem);
        printf("特征标志:                   %x
    ", pOptionalHeader->DllCharacteristics);
        printf("栈最大值:                   %x
    ", pOptionalHeader->SizeOfStackReserve);
        printf("栈初始值:                   %x
    ", pOptionalHeader->SizeOfStackCommit);
        printf("堆最大值:                   %x
    ", pOptionalHeader->SizeOfHeapReserve);
        printf("堆初始值:                   %x
    ", pOptionalHeader->SizeOfHeapCommit);
        printf("数据目录个数:               %x
    ", pOptionalHeader->NumberOfRvaAndSizes);
    
        //读取数据目录表信息
    
        PIMAGE_DATA_DIRECTORY pDataDirectory = pOptionalHeader->DataDirectory;
        
        //循环读取出数据目录中的相对虚拟地址和大小
    
        DWORD i = 0;
        while (i != 0x10)
        {
            //显示相对虚拟地址
            printf("第 %d 个相对虚拟地址  %7x", i, pDataDirectory[i].VirtualAddress);
            printf("         大小为:     %7x
    ", pDataDirectory[i].Size);
            i++;
        }
    
        //区段头表
    
        PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNTHeader);
    
        //循环输出,区段表信息,可以用两种方式判断结束,一个是文件头给出的区段的数量
        //可以用那个,也可以判断最后一个全零的区段头
        int j = 0;
        while (j<pOptionalHeader->NumberOfRvaAndSizes)
        {
            //输出或者获取每一个pSectionHeader中的成员
            printf("名称:%7x   V0ffset:%7x   VSize:%7x 
      ROffset:%7x   RSize:%7x    标志:%7x
    ",
                pSectionHeader->Name,                 //区段名称
                pSectionHeader->VirtualAddress,       //起始的相对虚拟地址
                pSectionHeader->Misc,                 //加载后区段大小
                pSectionHeader->PointerToRawData,     //文件偏移
                pSectionHeader->SizeOfRawData,          //区段大小,文件中
                pSectionHeader->Characteristics          //区段的属性
                
                );
            ++pSectionHeader;
            j++;
        }
    
    
    
    
        ////计算偏移量
        //DWORD CalcOffect(DWORD Rva)
        //{
        //    //获取NT头
        //    PIMAGE_NT_HEADERS32 pNTHeader = (PIMAGE_NT_HEADERS32)((long)pFile + (PIMAGE_DOS_HEADER)pFile->e_lfanew);
        //    //获取区段头表
        //    PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNTHeader);
        //    //循环比较它在哪个区段中,不在这个区段就继续循环,注意假如
        //    //VirtualAddress比SizeOfRawData大的话,说明大出来的部分是未初始化的数据,所以这里要用SizeOfRawData
        //    while (!(Rva) > pSectionHeader->VirtualAddress&&Rva <
        //        pSectionHeader->VirtualAddress + pSectionHeader->SizeOfRawData))
        //    {
        //        ++pSectionHeader;
        //        //防止错误的PE文件引发崩溃
        //        if (pSectionHeader->PointerToRawData == 0)
        //            return 0;
        //    }
        //    return Rva - pSectionHeader->VirtualAddress + pSectionHeader->PointerToRawData;
        //};
        return 0;
    
        }
  • 相关阅读:
    【洛谷P2922】秘密消息【Trie】
    数据结构实验之链表三:链表的逆置
    数据结构实验之链表三:链表的逆置
    数据结构实验之链表一:顺序建立链表
    数据结构实验之链表一:顺序建立链表
    数据结构实验之链表二:逆序建立链表
    数据结构实验之链表二:逆序建立链表
    顺序表应用6:有序顺序表查询
    顺序表应用6:有序顺序表查询
    顺序表应用5:有序顺序表归并
  • 原文地址:https://www.cnblogs.com/Alyoyojie/p/5329278.html
Copyright © 2011-2022 走看看