zoukankan      html  css  js  c++  java
  • [原创]手写一个PE文件

    手写一个PE文件,首先要对PE文件有一个基本的了解。这里使用的工具是hex workshop6.5。

    一、开始为一个结构体,我们来看一下:

    typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
        WORD   e_magic;                     // Magic number
        WORD   e_cblp;                      // Bytes on last page of file
        WORD   e_cp;                        // Pages in file
        WORD   e_crlc;                      // Relocations
        WORD   e_cparhdr;                   // Size of header in paragraphs
        WORD   e_minalloc;                  // Minimum extra paragraphs needed
        WORD   e_maxalloc;                  // Maximum extra paragraphs needed
        WORD   e_ss;                        // Initial (relative) SS value
        WORD   e_sp;                        // Initial SP value
        WORD   e_csum;                      // Checksum
        WORD   e_ip;                        // Initial IP value
        WORD   e_cs;                        // Initial (relative) CS value
        WORD   e_lfarlc;                    // File address of relocation table
        WORD   e_ovno;                      // Overlay number
        WORD   e_res[4];                    // Reserved words
        WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
        WORD   e_oeminfo;                   // OEM information; e_oemid specific
        WORD   e_res2[10];                  // Reserved words
        LONG   e_lfanew;                    // File address of new exe header
      } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; 

    首先e_magic应为0x5a4d,ANSI对应为“MZ”。还有一个关键的就是e_lfanew,指向IMAGE_NT_HEADER的开始位置。根据

    由于存储的方式是地位存放低字节,高位存放高字节,所以开始本来是0x5A4D,结果变成了4D5A,到D8000000的时候,这个结构体结束。

    后面是一段DOS的程序,然后是IMAGE_NT_HEADER结构,D800000000(其实真正的数据时0000‘00d8),指向后面的SIGNATURE,即00004550.ANSI为“PE00”,表示PE的有效性。我们可以使用ctrl+G,然后输入十六进制数据“000000D8”,直接跳转到该位置。

    下面,我们再来看看 IMAGE_NT_HEADER的结构

    typedef struct _IMAGE_NT_HEADERS
    {
         DWORD Signature;
         IMAGE_FILE_HEADER FileHeader;
         IMAGE_OPTIONAL_HEADER OptionalHeader;
    } IMAGE_NT_HEADERS;

    为了编程方便,windows为DOS文件标记和PE文件标记都定义了宏标识。

    #define IMAGE_DOS_HEADER         0x5A4D          //MZ
    #define IMAGE_NT_SIGNATURE       0x00004550   // PE00

    二、了解了PE的文件结构,我们就可以来写一个PE文件

    特别要注意位置的相对性,因为hex workshop是可调节大小的。

     这样,第一个结构体就差最后一个数据了,那就是e_lfanew的值(我这里写了,为42000000,实际为00000042,即下一行的开始)。

    42000000之后的数据就代表了dos程序,虽然是几个0。而42000000(实际是0000‘0042),指向的是下一行的开始,即IMAGE_NT_HEADERS的开始部分。

    而且只要这个位置的值是ANSI的PE00,则表示这个文件时一个PE文件:

    这样,一个PE文件就完成了,我们保存为pe.exe,等待下一步的验证。

    三、PE的验证

    在王艳萍的windows程序设计中,有涉及到PE文件的验证,我们就以书中代码设计一个程序,用来验证程序是否是PE文件。我对其中代码进行了修改,代码如下:

    void CCheckDlg::OnButton1() 
    {
        CFileDialog dlg(TRUE);
        if(dlg.DoModal()!=IDOK)
            return;
        HANDLE hFile=::CreateFile(dlg.GetFileName(),GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
        if(hFile==INVALID_HANDLE_VALUE)
        {
            MessageBox("无效文件","validpe",MB_OK);
        }
        IMAGE_DOS_HEADER dosHeader;
        IMAGE_NT_HEADERS32 ntHeader;
    
        BOOL bValid=FALSE;
        DWORD dwRead;
        ::ReadFile(hFile,&dosHeader,sizeof(dosHeader),&dwRead,NULL);
        if(dwRead==sizeof(dosHeader))
        {
            if(dosHeader.e_magic==IMAGE_DOS_SIGNATURE)
            {
                if(::SetFilePointer(hFile,dosHeader.e_lfanew,NULL,FILE_BEGIN)!=-1)
                {
                    ::ReadFile(hFile,&ntHeader,sizeof(ntHeader),&dwRead,NULL);
                    if(ntHeader.Signature==IMAGE_NT_SIGNATURE)
                        bValid=TRUE;
                }
            }
        }
        if(bValid)
            MessageBox("是一个PE格式的文件","提示",MB_OK);
        else
        {
            MessageBox("不是一个PE格式的文件","提示",MB_OK);
        }
        ::CloseHandle(hFile);
        return;
    }

     工程下载:https://files.cnblogs.com/tk091/PECheck.rar

  • 相关阅读:
    我最讨厌画图,这辈子我都不想再画图
    bzoj1218[HNOI2003]激光炸弹
    bzoj1196[HNOI2006]公路修建问题
    bzoj1588[HNOI2002]营业额统计
    bzoj2039[2009国家集训队]employ人员雇佣
    bzoj3874[Ahoi2014]宅男计划
    bzoj2282[Sdoi2011]消防
    bzoj1798[Ahoi2009]Seq 维护序列seq
    bzoj4003[JLOI2015]城池攻占
    bzoj2809[Apio2012]dispatching
  • 原文地址:https://www.cnblogs.com/tk091/p/2457464.html
Copyright © 2011-2022 走看看