欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]学习PE写的一个添加节区的工具

[原创]学习PE写的一个添加节区的工具

前段时间学习PE写了一个添加节区的小工具,拿计算器测试了一下,可以添加90多个节区.
先介绍一下手动添加节区的方法
方法一:(适用于最后一个节区头部与第一个节区数据之间有0x28字节的空间)


1.添加节区数据(文件对齐值)

2.修改节数量

3.添加IMAGE_SECTION_HEADER

4.修改SizeOfImage


方法二:重新编辑PE头(适用于最后一个节区头部与第一个节区数据之间没有0x28字节的空间)

1.把NT头 + 节区头部 复制粘贴到Dos Stub

2.修改DOS头的e_lfanew偏移为原Dos Stub位置

3.调用方法1


方法三:扩充PE头

1.PE头部后面添加一个文件对齐值的大小(0x200)

2.修改SizeOfHeaders

3.修正所有节区的文件偏移

4.调用方法1


以下是部分代码

IMAGE_SECTION_HEADER CMyPEFile::AddSection(CString strSectionName, DWORD dwSectionSize)

{

  DWORD dwSectionOffset = GetSectionOffset(0);

  WORD wNumberOfSections = GetNumberOfSections();

  dwSectionOffset += wNumberOfSections * sizeof(IMAGE_SECTION_HEADER);

  DWORD dwSizeOfHeader = GetSizeOfHeaders();

  IMAGE_SECTION_HEADER AddSectionHeader = {0};

  DWORD dwFreeLen = dwSizeOfHeader - dwSectionOffset;

  if(dwFreeLen >= sizeof(IMAGE_SECTION_HEADER))

  {

    /*

    方法一:(适用于最后一个节区头部与第一个节区数据之间有0x28字节的空间)

    1.添加节区数据(文件对齐值)

    2.修改节数量

    3.添加IMAGE_SECTION_HEADER

    4.修改SizeOfImage

    */

    SetNumberOfSections(wNumberOfSections + 1);

    m_NtHeaders.FileHeader.NumberOfSections += 1;

    DWORD SectionAlignment = CheckSectionAlignment(dwSectionSize);

    DWORD dwSizeofImage = GetSizeOfImage();

    SetSizeOfImage(dwSizeofImage + SectionAlignment);

    IMAGE_SECTION_HEADER SectionHeader = {0};

    GetSectionHeader(&SectionHeader, wNumberOfSections - 1);

    ZeroMemory(&AddSectionHeader, sizeof(IMAGE_SECTION_HEADER));

    memcpy(AddSectionHeader.Name, strSectionName, 

          strSectionName.GetLength() > 8 ? 8: strSectionName.GetLength());

    AddSectionHeader.Misc.VirtualSize = (DWORD)dwSectionSize;

    AddSectionHeader.VirtualAddress = 

      CheckSectionAlignment(SectionHeader.VirtualAddress 

      + SectionHeader.Misc.VirtualSize);

    AddSectionHeader.SizeOfRawData = CheckFileAlignment(dwSectionSize);

    AddSectionHeader.PointerToRawData =SectionHeader.PointerToRawData 

      + SectionHeader.SizeOfRawData;

    AddSectionHeader.Characteristics = IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;

    SetSectionHeader(AddSectionHeader, wNumberOfSections);

    SeekToEnd();

    TCHAR* lpBuf = new TCHAR[AddSectionHeader.SizeOfRawData];

    if (lpBuf)

    {

      ZeroMemory(lpBuf, AddSectionHeader.SizeOfRawData);

      Write(lpBuf, AddSectionHeader.SizeOfRawData);

      delete[] lpBuf;

      lpBuf = NULL;

      if (GetNumberOfRvaAndSizes() > IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT)

      {

        ZeroBoundImportDataDir();

      }

    }

  }

  else if (dwFreeLen < sizeof(IMAGE_SECTION_HEADER))

  {

    DWORD dwStubLen = m_DosHeader.e_lfanew - sizeof(IMAGE_DOS_HEADER);

    if ((dwFreeLen + dwStubLen) >= sizeof(IMAGE_SECTION_HEADER))

    {

      /*

      方法二:重新编辑PE头(适用于最后一个节区头部与第一个节区数据之间没有0x28字节的空间)

      1.把NT头 + 节区头部 复制粘贴到Dos Stub

      2.修改DOS头的e_lfanew偏移为原Dos Stub位置

      3.调用方法1

      */

      DWORD dwNumOfReads = dwSectionOffset - m_DosHeader.e_lfanew;

      Seek(m_DosHeader.e_lfanew, CFile::begin);

      char* lpBuffer = new char[dwNumOfReads];

      if (lpBuffer)

      {

        Read(lpBuffer, dwNumOfReads);

        DWORD dwlfamew = sizeof(IMAGE_DOS_HEADER);

        Seek(dwlfamew, CFile::begin);

        Write(lpBuffer, dwNumOfReads);

        SetEe_lfanew(dwlfamew);

        AddSection(strSectionName,  dwSectionSize);

        delete[] lpBuffer;

        lpBuffer = NULL;

      }

    }

    else

    {

      /*

      方法三:扩充PE头

      1.PE头部后面添加一个文件对齐值的大小(0x200)

      2.修改SizeOfHeaders

      3.修正所有节区的文件偏移

      4.调用方法1

      */

      DWORD dwSizeOfHeader = GetSizeOfHeaders();

      DWORD dwAddSize = GetFileAlignment();

      DWORD dwBufLen = GetPeFileSize() - dwSizeOfHeader;

      char* lpBuffer = new char[dwBufLen];

      if (lpBuffer)

      {

        Seek(dwSizeOfHeader, CFile::begin);

        UINT nRet = Read(lpBuffer, dwBufLen);

        Seek(dwSizeOfHeader, CFile::begin);

        char* lpSectionBuf = new char[dwAddSize];

        ZeroMemory(lpSectionBuf, dwAddSize);

        if (lpSectionBuf)

        {

          Write(lpSectionBuf, dwAddSize);

          Write(lpBuffer, dwBufLen);

          SetSizeOfHeaders(dwSizeOfHeader + dwAddSize);

          AddAllSectionPointerOfRawData(dwAddSize);

          AddSection(strSectionName,  dwSectionSize);

          delete[] lpSectionBuf;

          lpSectionBuf = NULL;

        }

        delete[] lpBuffer;

        lpBuffer = NULL;

      }

    }

  }

  ReadAllHeader();

  return AddSectionHeader;

}


参考资料:http://bbs.pediy.com/showthread.php?t=103092
工具 AddSection.7z

上传的附件 AddSection.7z

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功