zoukankan      html  css  js  c++  java
  • 基础加壳程序

    摘要:     给32位的PE文件加壳,包括exe, dll, ocx, 服务程序,com组件等,差不多所有的PE文件都可以用这个给加上了。我写的这个程序需要插上一个U盘,随便有一个U盘就可以,然后才能给程序加壳,加壳的程序也依靠这个U盘才能运行,有点意思吧。先把程序最主要的函数写到下面。
     

    //-------------------------------------------------------------------

    // 功能: 加壳

    // 参数: oldpe - 加壳前的PE文件

    //       shell - 外壳

    //       newpe - 加壳后的PE文件

    //       devstr - device string 设备字符串

    // 返回: 是否加壳成功

    // 说明: 这样合并之后, oldpe, shell也被改变了, 不能用了

    //       she就是外壳使用的那个段

    //       一般roloc就是在最后, 如果万一碰到不是在最后的, 这里就不能加上壳了

    //       1-在oldpe中, 2-在shell中, 3-在newpe中

    //       R表示在文件中偏移raw, V表示在内存中偏移virtual, T表示有效长度true

    //

    bool CombinShell(CPeManager* oldpe, CPeManager* shell, CPeManager* newpe, char* devstr)

    {

      //保存到壳里面

      TShellHead SH = {0};

      strcpy(SH.Feature, devstr);

      SH.ImageBase = oldpe->GetImageBase();

      SH.OldEntry = oldpe->GetEntryPoint();

      SH.OldImport = oldpe->GetImportVpos();

      SH.OldLastSection = *(oldpe->GetLastSection());

      SH.OldBoundImportDataDir = *(oldpe->GetBoundImportDataDir());

      SH.OldImportDataDir = *(oldpe->GetImportDataDir());

      SH.OldIatDataDir = *(oldpe->GetIatDataDir());

      //--给新PE申请一个空间--------------

      newpe->m_BufSize = oldpe->m_FileSize + shell->m_FileSize + 0x8000;

      newpe->m_Buf = new BYTE[newpe->m_BufSize];

      ::ZeroMemory(newpe->m_Buf, newpe->m_BufSize);

      //--把旧PE复制到新PE中去------------

      DWORD last1_Rpos = oldpe->GetLastRpos();

      DWORD last1_Vpos = oldpe->GetLastVpos();

      DWORD last1_Rsize = oldpe->GetLastRsize();

      DWORD last1_Tsize = oldpe->GetLastTsize();

      memcpy(newpe->m_Buf, oldpe->m_Buf, (last1_Rpos + last1_Rsize)); 

      //--把壳复制到新PE中去-------------------

      DWORD she2_Rpos = shell->GetSheRpos();

      DWORD she2_Vpos = shell->GetSheVpos();

      DWORD she2_Tsize = shell->GetSheTsize();

      DWORD she2_Rsize = shell->GetSheRsize();

      DWORD she3_Vpos = last1_Vpos + oldpe->AlignV(last1_Rsize);

      DWORD she3_Rpos = last1_Rpos + oldpe->AlignV(last1_Rsize);

      int base_move = oldpe->GetImageBase() - shell->GetImageBase(); 

      int Vpos_move = she3_Vpos - she2_Vpos;

      shell->ModifyReloc(base_move, Vpos_move);

      shell->ModifyImport(Vpos_move);

      memcpy(newpe->m_Buf + she3_Rpos, shell->m_Buf + she2_Rpos, she2_Rsize);

      //--修正新PE的段头表--------------------------------

      DWORD last3_Tsize = she3_Vpos + she2_Rsize - last1_Vpos;

      DWORD last3_Rsize = oldpe->AlignR(last3_Tsize);

      newpe->GetLastSection()->Misc.VirtualSize = last3_Rsize;

      newpe->GetLastSection()->SizeOfRawData = last3_Rsize;

      DWORD file3_size = last1_Rpos + last3_Rsize;

      DWORD image3_size = last1_Vpos + last3_Rsize;

      //--合并重定位表--------------------

      if(oldpe->GetRelocSection() != 0)

      {

        //保存到壳里面

        SH.OldRelocDataDir = *(oldpe->GetRelocDataDir());

        SH.OldRelocSection = *(oldpe->GetRelocSection());

        DWORD reloc1_Rpos = oldpe->GetRelocRpos();

        DWORD reloc1_Tsize = oldpe->GetRelocTsize();

        DWORD reloc2_Rpos = shell->GetRelocRpos();

        DWORD reloc2_Tsize = shell->GetRelocTsize();

        DWORD reloc3_Rpos = last1_Rpos + last3_Rsize;

        DWORD reloc3_Vpos = last1_Vpos + oldpe->AlignV(last3_Rsize);

        DWORD reloc3_Tsize = reloc1_Tsize + reloc2_Tsize;

        DWORD reloc3_Rsize = oldpe->AlignR(reloc3_Tsize + 8);

            

        //把旧PE的重定位表复制到新PE中

        memcpy(newpe->m_Buf + reloc3_Rpos, oldpe->m_Buf + reloc1_Rpos, reloc1_Tsize);

        //把壳的重定位表复制到新的PE中去

        memcpy(newpe->m_Buf + reloc3_Rpos + reloc1_Tsize, shell->m_Buf + reloc2_Rpos, reloc2_Tsize);

        //--修正新PE的重定位地址---------

        newpe->GetRelocSection()->Misc.VirtualSize = reloc3_Rsize;

        newpe->GetRelocSection()->SizeOfRawData = reloc3_Rsize;

        newpe->GetRelocSection()->PointerToRawData = reloc3_Rpos;

        newpe->GetRelocSection()->VirtualAddress = reloc3_Vpos;

        newpe->GetRelocDataDir()->Size = reloc3_Tsize;

        newpe->GetRelocDataDir()->VirtualAddress = reloc3_Vpos;

        file3_size = reloc3_Rpos + reloc3_Rsize;

        image3_size = reloc3_Vpos + reloc3_Rsize;     

      }

      //--拷贝附加数据--------------------

      if(oldpe->GetFixTsize() != 0)

      {

        DWORD fix1_Rpos = oldpe->GetFixRpos();

        DWORD fix1_Tsize = oldpe->GetFixTsize();

        memcpy(newpe->m_Buf + file3_size, oldpe->m_Buf + fix1_Rpos, fix1_Tsize);

        file3_size += fix1_Tsize;

      }

      //--修改新PE文件的头部----------------------------

      //入口地址

      if(oldpe->IsDLL())

        newpe->GetOptionalHeader()->AddressOfEntryPoint = shell->GetExportFuncVpos("_DllEntry@12") + Vpos_move;

      else

        newpe->GetOptionalHeader()->AddressOfEntryPoint = shell->GetExportFuncVpos("_ExeEntry@0") + Vpos_move;

     

      //导入表地址

      newpe->GetImportDataDir()->VirtualAddress = shell->GetImportDataDir()->VirtualAddress + Vpos_move;

      newpe->GetImportDataDir()->Size = shell->GetImportDataDir()->Size;

      newpe->GetIatDataDir()->VirtualAddress = 0;

      newpe->GetIatDataDir()->Size = 0;

      newpe->GetBoundImportDataDir()->VirtualAddress = 0;

      newpe->GetBoundImportDataDir()->Size = 0;

      //映像大小

      newpe->GetOptionalHeader()->SizeOfImage = image3_size; 

      newpe->GetOptionalHeader()->CheckSum = 0;

      newpe->m_FileSize = file3_size;

      //每个段都置为可写

      int sec_num = newpe->GetSectionNum();

      IMAGE_SECTION_HEADER* sec_hs = newpe->GetSectionHeaders();

      for(int i = 0; i < sec_num; i++)

      {

        sec_hs[i].Characteristics |= 0x80000000;

      }

      //--保存TShellHead结构-----------------------

      TShellHead* pHead = newpe->GetShellHead(she3_Rpos, she2_Tsize);

      if(pHead == 0)

        return false;

      *pHead = SH;

      return true;

    }

    因为是个教学程序,界面很简单,下面就是打开了一个扫雷程序。

    加壳后的扫雷程序运行时:

    如果没有U盘,就会出现:

    如果你喜欢这个程序,请留言,或者联系我。

  • 相关阅读:
    HDU2586 How far away?(tarjan的LCA)
    You Raise Me Up
    POJ2891 Strange Way to Express Integers(中国剩余定理)
    POJ2142 The Balance(扩展欧几里得)
    HDU 1166模仿大牛写的线段树
    NetWord Dinic
    HDU 1754 线段树裸题
    hdu1394 Minimum Inversion Number
    hdu2795 Billboard
    【完全版】线段树
  • 原文地址:https://www.cnblogs.com/lzjsky/p/1881992.html
Copyright © 2011-2022 走看看