• 在PE文件的第一个代码节里添加代码


    #include "stdafx.h"

    #define MBXADDR 0x77D66534

    #define CODE_LEN 18
    #define CODE_RV1 0xD
    #define CODE_RV2 0x12
    unsigned char CODE[CODE_LEN]={0x6A,0x00,0x6A,0x00,0x6A,0x00,0x6A,0x00,0xE8,0x00,0x00,0x00,0x00,0xE9,0x00,0x00,0x00,0x00};


    //返回对齐后的大小,real实际大小,raw对齐大小参数,Size为对齐后大小
    long AlignSize(int Real,int Raw)
    {
         long Size = ( Real % Raw == 0 ? Real:Real/Raw*Raw+Real%Raw*Raw); 

        return Size;
    }

    /////代码节添加代码///////

    /*1. 读文件到FileBuffer */
    unsigned char* FileBuffer(const char* FileName , const char* Mode,long* pSize)
    {
         unsigned char* Heap = NULL;
         errno_t Err;
         FILE* Stream;
         Err = fopen_s(&Stream,FileName,Mode);
         long Size = 0L;
         if(Err != 0)
         {
             if(DEBUG)
                 perror("Open file error:");
                 printf("Open %s as %s mode error! ",FileName,Mode);
             return NULL;
         }
         // 文件大小
         fseek(Stream,0L,SEEK_END);
         Size = ftell(Stream);
         *pSize = Size;
         fseek(Stream,0L,SEEK_SET);
         //写入到FileBuffer
         Heap = (unsigned char*)malloc(sizeof(char)*Size);
         if(Heap == NULL)
         {
             if(DEBUG)
                 printf("Create FileBuffer Error! ");
             fclose(Stream);
             return NULL;
         }

        fread(Heap,sizeof(char),Size,Stream);
         fclose(Stream);

        return Heap;

    }


    /*2.在FileBuffer里面操作节:添加代码到第一个节 */
    int InsertCodeToPEText(unsigned char* Buffer,unsigned char* Code,int CodeSize)
    {
         //判断是不是PE文件,MZ标志和PE标志
         PIMAGE_DOS_HEADER pDosHeader;
         PIMAGE_NT_HEADERS32 pNtHeader32;
         PIMAGE_NT_HEADERS64 pNtHeader64;
         PIMAGE_SECTION_HEADER pSectionHeader;
         pDosHeader = (PIMAGE_DOS_HEADER)Buffer;

       
         if(pDosHeader->e_magic != 0x5A4D)
         {
             perror("Not PE format file ! ");
             return -1;
         }
         pNtHeader32 = (PIMAGE_NT_HEADERS32)(Buffer+pDosHeader->e_lfanew);
         if(pNtHeader32->Signature != 0x4550)
         {
             perror("PE File format fail! ");
             return -1;
         }
         if (pNtHeader32->FileHeader.SizeOfOptionalHeader != 0xE0)
         {
             pNtHeader64 =(PIMAGE_NT_HEADERS64)pNtHeader32;
             perror("PE is 64Bit! ");
             return 1;
         }
         //第一个节的文件对齐空间够不够放18个字节
          pSectionHeader = (PIMAGE_SECTION_HEADER)(pNtHeader32+1);
          int PySize,FAlignSize;
          FAlignSize = pSectionHeader->SizeOfRawData;
          PySize =pSectionHeader->Misc.VirtualSize;
          if(FAlignSize - PySize < CODE_LEN )
          {
              perror("First Section Free Buffer Less!");
              return -1;
          }
          unsigned char CodeA[100];
          int x ;
          for(x=0 ;x < CodeSize;x++)
          {
              CodeA[x] = Code[x];
          }
         //第一个节的最后位置的内存偏移地址和文件偏移地址的差,用来计算E8 E9 和OEP的位置,要用到的PE有 OP_Header->OEP,Section_h->praw/va sraw/viualsize
          long Distance = pSectionHeader->VirtualAddress - pSectionHeader->PointerToRawData;  //IMAGEBUFFER和FILEBUFFER的距离

         long InsertAV = pNtHeader32->OptionalHeader.ImageBase + pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize;                                            //添加代码的VA位置

         long OldOEP = pNtHeader32->OptionalHeader.ImageBase + pNtHeader32->OptionalHeader.AddressOfEntryPoint;  //原文件的OEP+ImageBase

        

         long* JMP = (long*)(CodeA+14);
          long* CALL = (long*)(CodeA+9);
          *CALL = MBXADDR - InsertAV - CODE_RV1;                                         //CALL MessageBoxW 的X位置

         *JMP = OldOEP - InsertAV - CODE_RV2;                                           //JMP回OEP的X位置
          /*
          for(x=0;x<4;x++)
          {
              CodeA[9+x]=CALL%0x100;
              CALL = CALL/0x100;
              CodeA[14+x]=JMP%0x100;
              JMP = JMP/0x100;
          }
          */

         unsigned char*  BuffRA = Buffer + pSectionHeader->PointerToRawData+pSectionHeader->Misc.VirtualSize;
          int i ;
          for( i=0; i<CodeSize;i++)
          {
              BuffRA[i]=CodeA[i];
          }
         
          pNtHeader32->OptionalHeader.AddressOfEntryPoint = InsertAV - pNtHeader32->OptionalHeader.ImageBase;
         return 0;
    }


    /*3.将FileBuffer保存到新文件*/
    int SaveBuffer(unsigned char* Buffer,long Size,const char* NewFileN) // 字节为长度单位
    {
         errno_t Err;
         FILE* Stream;
         Err = fopen_s(&Stream,NewFileN,"wb");
         if(Err != 0)
         {
             if(DEBUG)
                 printf("Create New File %s error! ",NewFileN);
             return -1;
         }
        
         fwrite(Buffer,sizeof(char),Size,Stream);
         fclose(Stream);

        return 0;
    }

    /////////////////////////////////////////////////////////////

    #include "stdafx.h"
    #define CODE_LEN 18
    extern unsigned char CODE[CODE_LEN];
    int _tmain(int argc, _TCHAR* argv[])
    {
         long Size;
         unsigned char* Buff = FileBuffer("notepad.exe" , "rb",&Size);
         if(Buff == NULL)
             return -1;
         InsertCodeToPEText(Buff,CODE,CODE_LEN);
         SaveBuffer(Buff,Size,"notepad_new.exe");
         return 0;
    }

  • 相关阅读:
    html 复选框
    html 单选框
    C++创建类的对象(类的初始化)的方法
    C++创建类的对象(类的初始化)的方法
    C#基础实现URL Unicode编码,编码、解码相关整理
    C#基础实现URL Unicode编码,编码、解码相关整理
    js 发送http请求
    js 发送http请求
    C++的三种实例化对象方式
    C++的三种实例化对象方式
  • 原文地址:https://www.cnblogs.com/killad/p/7192521.html
Copyright © 2020-2023  润新知