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盘,就会出现:

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

  • 相关阅读:
    JVM — 类加载机制
    java 异常处理
    (前篇:NIO系列 推荐阅读) Java NIO 底层原理
    (六:NIO系列) 相关设计模式
    (五:NIO系列) Reactor模式
    (四:NIO系列) Java NIO Selector
    (三:NIO系列) Java NIO Channel
    (二:NIO系列) Java NIO Buffer
    (一:NIO系列)JAVA NIO 简介
    java 线程池(线程的复用)
  • 原文地址:https://www.cnblogs.com/lzjsky/p/1881992.html
Copyright © 2011-2022 走看看