[C++] 纯文本查看 复制代码
#include "iostream"
#include <windows.h>
#define size_shellcode 0x12
#define FILEPATH_OUT "c:/123.exe"
#define FILEPATH_IN "C:/Windows/system32/notepad.exe"
#define messagebox_add 0x77b101c8
BYTE shellcode[] = {
0x6A,00,0x6A,00,0x6A,00,0x6A,00,
0XE8,00,00,00,00,
0XE9,00,00,00,00
};
// exe->filebuffer 返回值为计算所得文件大小
int ReadPEFile(char* file_path,PVOID* pFileBuffer)
{
FILE* pfile =NULL;// 文件指针
DWORD file_size=0;
LPVOID pTempFilebuffer =NULL;
pfile =fopen(file_path,"rb");// 如果有新的指针,就要进行判断
if(!pfile )
{
printf("打开exe文件失败!\n");//如果分配失败就要关闭文件、释放动态内存、指针指向NULL
return 0;
}
fseek(pfile ,0,SEEK_END);
file_size=ftell(pfile);
fseek(pfile ,0,SEEK_SET);
pTempFilebuffer=malloc(file_size);
if(!pTempFilebuffer)
{
printf("分配空间失败!\n");//如果分配失败就要关闭文件、释放动态内存、指针指向NULL
fclose(pfile );
return 0;
}
size_t n=fread(pTempFilebuffer,file_size,1,pfile );
if(!n)
{
printf("分配空间失败!\n");
fclose(pfile);
free(pTempFilebuffer);
return 0;
}
*pFileBuffer=pTempFilebuffer;
pTempFilebuffer=NULL;
fclose(pfile);
return file_size;
}
// filebuffer -> imagebuffer
DWORD CopyFileBufferToImageBuffer(PVOID pFileBuffer,PVOID* pImageBuffer)
{
// 初始化PE头部结构体
PIMAGE_DOS_HEADER pDosHeader =NULL;
PIMAGE_NT_HEADERS pNTHeader =NULL;
PIMAGE_FILE_HEADER pPEHeader =NULL;
PIMAGE_OPTIONAL_HEADER pOptionHeader =NULL;
PIMAGE_SECTION_HEADER pSectionHeader =NULL;
// 初始化IMAGE_BUFFER指针(temparay)
LPVOID pTempImagebuffer = NULL;
if(!pFileBuffer)
{
printf("(2pimagebuffer阶段)读取到内存的pfilebuffer无效!\n");
return 0 ;
}
if(*((PWORD)pFileBuffer)!=IMAGE_DOS_SIGNATURE)
{
printf("(2pimagebuffer阶段)不含MZ标志,不是exe文件!\n");
return 0;
}
pDosHeader=PIMAGE_DOS_HEADER(pFileBuffer);
pNTHeader=(PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
pPEHeader=(PIMAGE_FILE_HEADER)((DWORD)pNTHeader+4);
pOptionHeader=(PIMAGE_OPTIONAL_HEADER)((DWORD)pNTHeader+0x18);
// pSectionHeader=(PIMAGE_SECTION_HEADER)((DWORD)pDosHeader+pOptionHeader->SizeOfHeaders);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
// 分配动态内存
pTempImagebuffer =malloc(pOptionHeader->SizeOfImage);
if(!pTempImagebuffer)
{
printf("分配空间失败!\n");//如果分配失败就要关闭文件、释放动态内存、指针指向NULL
free(pTempImagebuffer);
return 0;
}
memset(pTempImagebuffer,0,pOptionHeader->SizeOfImage);
memcpy(pTempImagebuffer,pDosHeader,pOptionHeader->SizeOfHeaders);
PIMAGE_SECTION_HEADER pTempSectionHeader = pSectionHeader;
for(DWORD i=0;i<pPEHeader->NumberOfSections;i++,pTempSectionHeader++)
memcpy((void*)((DWORD)pTempImagebuffer+pTempSectionHeader->VirtualAddress)
,(void*)((DWORD)pDosHeader+pTempSectionHeader->PointerToRawData)
,pTempSectionHeader->SizeOfRawData);
*pImageBuffer=pTempImagebuffer;
pTempImagebuffer=NULL;
return pOptionHeader->SizeOfImage;
}
DWORD CopyImageBufferToNewBuffer(IN LPVOID pImageBuffer,OUT LPVOID* pNewBuffer)
{
// 初始化PE头部结构体
PIMAGE_DOS_HEADER pDosHeader =NULL;
PIMAGE_NT_HEADERS pNTHeader =NULL;
PIMAGE_FILE_HEADER pPEHeader =NULL;
PIMAGE_OPTIONAL_HEADER pOptionHeader =NULL;
PIMAGE_SECTION_HEADER pSectionHeader =NULL;
if(!pImageBuffer)
{
printf("分配空间失败!\n");//如果分配失败就要关闭文件、释放动态内存、指针指向NULL
free(pImageBuffer);
return 0;
}
if(*((PWORD)pImageBuffer)!=IMAGE_DOS_SIGNATURE)
{
printf("(2pimagebuffer阶段)不含MZ标志,不是exe文件!\n");
return 0;
}
pDosHeader=(PIMAGE_DOS_HEADER)pImageBuffer;
pNTHeader=(PIMAGE_NT_HEADERS)((DWORD)pDosHeader+pDosHeader->e_lfanew);
pPEHeader=(PIMAGE_FILE_HEADER)((DWORD)pNTHeader+4);
pOptionHeader=(PIMAGE_OPTIONAL_HEADER)((DWORD)pNTHeader+0x18);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
PIMAGE_SECTION_HEADER pSectionHeader1=pSectionHeader;
DWORD a=pOptionHeader->SizeOfHeaders;
for(DWORD q=0;q<pPEHeader->NumberOfSections;q++,pSectionHeader1++)
a+=pSectionHeader1->SizeOfRawData;
LPVOID pTempImagebuffer = NULL;
pTempImagebuffer=malloc(a);
if(!pTempImagebuffer)
{
printf("分配空间失败!\n");//如果分配失败就要关闭文件、释放动态内存、指针指向NULL
free(pTempImagebuffer);
return 0;
}
memset(pTempImagebuffer,0,a);
memcpy(pTempImagebuffer,pDosHeader,pOptionHeader->SizeOfHeaders);
pSectionHeader1=pSectionHeader;
for(int i=0;i<pPEHeader->NumberOfSections;i++,pSectionHeader1++)
memcpy((void*)((DWORD)pTempImagebuffer+pSectionHeader1->PointerToRawData),
(void*)((DWORD)pDosHeader+pSectionHeader1->VirtualAddress),
pSectionHeader1->SizeOfRawData);
*pNewBuffer=pTempImagebuffer;
pTempImagebuffer=NULL;
return a;
}
//newbuffer->存盘
int newbuffer_write2_exe(PVOID NewFileBuffer,DWORD FileSize, char* FilePath)
{
FILE* fp1 = fopen(FilePath,"wb");
if(fp1 != NULL)
{
fwrite(NewFileBuffer,FileSize,1,fp1);
}
fclose(fp1);
return 1;
}
void TestAddCodeInDataSec()
{
LPVOID pFileBuffer= NULL;
LPVOID pImageBuffer= NULL;
LPVOID pNewBuffer = NULL;
PIMAGE_DOS_HEADER pDosHeader =NULL;
PIMAGE_NT_HEADERS pNTHeader =NULL;
PIMAGE_FILE_HEADER pPEHeader =NULL;
PIMAGE_OPTIONAL_HEADER pOptionHeader =NULL;
PIMAGE_SECTION_HEADER pSectionHeader =NULL;
PBYTE codeBegin = NULL;
BOOL isOK=FALSE;
DWORD size=0;
ReadPEFile(FILEPATH_IN,&pFileBuffer);
if(!pFileBuffer)
{
printf("wenjian--shibaio");
return ;
}
CopyFileBufferToImageBuffer(pFileBuffer,&pImageBuffer);
if(!pImageBuffer)
{
printf("FileBuffer-->ImageBuffer失败");
free(pFileBuffer);
return ;
}
pDosHeader=PIMAGE_DOS_HEADER(pImageBuffer);
pNTHeader=(PIMAGE_NT_HEADERS)((DWORD)pImageBuffer+pDosHeader->e_lfanew);
pPEHeader=(PIMAGE_FILE_HEADER)((DWORD)pNTHeader+4);
pOptionHeader=(PIMAGE_OPTIONAL_HEADER)((DWORD)pNTHeader+0x18);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
if(((pSectionHeader->SizeOfRawData)-(pSectionHeader->Misc.VirtualSize))<size_shellcode)
{
printf("daimakongjianbugou");
free(pFileBuffer);
free(pImageBuffer);
}
codeBegin=(PBYTE)((DWORD)pImageBuffer+pSectionHeader->VirtualAddress+pSectionHeader->Misc.VirtualSize);
memcpy(codeBegin,shellcode,size_shellcode);
DWORD callAddr=(messagebox_add-(pOptionHeader->ImageBase+((DWORD)(codeBegin+0xD)-(DWORD)pImageBuffer)));
*(PDWORD)(codeBegin+9)=callAddr;
DWORD jmpAddr=((pOptionHeader->ImageBase+pOptionHeader->AddressOfEntryPoint)-(pOptionHeader->ImageBase+((DWORD)(codeBegin+size_shellcode)-(DWORD)pImageBuffer)));
*(PDWORD)(codeBegin+0xe)=jmpAddr;
pOptionHeader->AddressOfEntryPoint=(DWORD)codeBegin-(DWORD)pImageBuffer;
size=CopyImageBufferToNewBuffer(pImageBuffer,&pNewBuffer);
newbuffer_write2_exe(pNewBuffer,size, FILEPATH_OUT);
free(pFileBuffer);
free(pImageBuffer);
free(pNewBuffer);
}
int main()
{
TestAddCodeInDataSec();
return 0;
}