#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;
}