#include<stdio.h>
#include<windows.h>
DWORD Align(DWORD ad, DWORD alignment){
if(ad % alignment == 0){
return ad;
}else{
return ((ad / alignment) + 1) * alignment;
}
}
DWORD UpHeader(PVOID* pFileBuffer, PVOID* pNewFileBuffer){
return 0;
}
DWORD toLordPE(PSTR file_path, PVOID* pFileBuffer){
FILE *pFile;
DWORD FileSize;
pFile = fopen(file_path, "rb");
if(!pFile){
printf("文件打开失败!\n");
return 0;
}
fseek(pFile, 0, SEEK_END);
FileSize = ftell(pFile);
fseek(pFile, 0, SEEK_SET);
*pFileBuffer = malloc(FileSize);
if(!pFileBuffer){
printf("内存分配失败!\n");
return 0;
}
DWORD n = fread(*pFileBuffer, FileSize, 1, pFile);
if(!n){
printf("从文件读到内存失败!\n");
return 0;
}
fclose(pFile);
return FileSize;
}
DWORD AddSection(PSTR file_path, PVOID* pFileBuffer, DWORD FileSize, PVOID* pNewFileBuffer){
int isUpHeader = 0;
//DWORD FileSize = toLordPE(file_path, pFileBuffer);
DWORD FileTotal = FileSize + 0x1000;
printf("%x\n",*pFileBuffer);
*pNewFileBuffer = malloc(FileTotal);
printf("%x\n",pNewFileBuffer);
printf("%x\n",*pNewFileBuffer);
if(!pNewFileBuffer){
printf("新增节内存分配失败!\n");
return 0;
}
memset(*pNewFileBuffer, 0, FileTotal);
memcpy(*pNewFileBuffer, *pFileBuffer, FileSize);
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
//printf("1\n");
printf("%x\n",*((PWORD)*pNewFileBuffer));
if (*((PWORD)*pNewFileBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("没有MZ标志!\n");
//free(*pNewFileBuffer);
return 0;
}
pDosHeader = (PIMAGE_DOS_HEADER)*pNewFileBuffer;
if (*((PDWORD)((DWORD)(*pNewFileBuffer) + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
//printf("%x\n",pDosHeader->e_lfanew);
//printf("%x\n",*((PDWORD)((DWORD)(*pNewFileBuffer) + pDosHeader->e_lfanew)));
printf("没有PE标志!\n");
//free(*pNewFileBuffer);
return 0;
}
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)(*pNewFileBuffer) + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);
PIMAGE_SECTION_HEADER pSectionHeaderTemp = pSectionHeader;
for (DWORD i = 0; i < pPEHeader->NumberOfSections; i++, pSectionHeaderTemp++)
{
// for结束后,pSectionHeaderTemp指向最后一个节表的后面
//printf("%x\n",i);
}
// pLastSectionHeaderTemp 指向最后一个节表
PIMAGE_SECTION_HEADER pLastSectionHeaderTemp = pSectionHeaderTemp-1;
/*
PBYTE Temp = (PBYTE)pSectionHeaderTemp;
printf("%x\n",*(Temp+0));
printf("%x\n",*(Temp+1));
printf("%x\n",*(Temp+2));
printf("%x\n",*(Temp+3));
*/
// 节表后有没有多余空间
// 多余空间是不是0
if((DWORD)pSectionHeaderTemp + IMAGE_SIZEOF_SECTION_HEADER * 2 <= (pOptionHeader->SizeOfHeaders + (DWORD)(*pNewFileBuffer))){
PBYTE pSTemp = (PBYTE)pSectionHeaderTemp;
for(i = 0; i < (IMAGE_SIZEOF_SECTION_HEADER * 2); i++, pSTemp++){
if(*pSTemp){
// printf("%x\n",*(pSTemp+0));
printf("节表后面有数据,不能插入节表,尝试头抬升!\n");
// UpHeader(&pFileBuffer, &pNewFileBuffer);
isUpHeader = 1;
break;
}
}
printf("节表后有足够空间,且数据为0\n");
}else{
printf("节表后没有多余空间,尝试头抬升!\n");
isUpHeader = 1;
// UpHeader();
}
if(isUpHeader){
if((DWORD)pNTHeader - (DWORD)*pNewFileBuffer - sizeof(IMAGE_DOS_HEADER) >= IMAGE_SIZEOF_SECTION_HEADER * 2){
printf("抬升头\n");
memcpy((PVOID)((DWORD)*pNewFileBuffer + sizeof(IMAGE_DOS_HEADER)), pNTHeader, (DWORD)pSectionHeaderTemp - (DWORD)pNTHeader);
pDosHeader->e_lfanew = sizeof(IMAGE_DOS_HEADER);
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)(*pNewFileBuffer) + pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);
pSectionHeaderTemp = pSectionHeader;
for (DWORD i = 0; i < pPEHeader->NumberOfSections; i++, pSectionHeaderTemp++)
{
// for结束后,pSectionHeaderTemp指向最后一个节表的后面
//printf("%x\n",i);
}
// pLastSectionHeaderTemp 指向最后一个节表
pLastSectionHeaderTemp = pSectionHeaderTemp-1;
if (*((PDWORD)((DWORD)(*pNewFileBuffer) + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("(抬升后)没有PE标志!\n");
return 0;
}
printf("抬升成功\n");
memset(pSectionHeaderTemp, 0, IMAGE_SIZEOF_SECTION_HEADER * 2);
}else{
printf("(DOS Sub)没有足够的空间插入节表,不可以头抬升!\n");
return 0;
}
}
printf("插入节表\n");
memcpy(pSectionHeaderTemp, ".tttt", 8);
pSectionHeaderTemp->Misc.VirtualSize = 0x1000;
// pSectionHeaderTemp->VirtualAddress = pOptionHeader->SizeOfImage;
DWORD z = pLastSectionHeaderTemp->Misc.VirtualSize > pLastSectionHeaderTemp->SizeOfRawData ? pLastSectionHeaderTemp->Misc.VirtualSize : pLastSectionHeaderTemp->SizeOfRawData;
pSectionHeaderTemp->VirtualAddress = pLastSectionHeaderTemp->VirtualAddress + Align(z, pOptionHeader->SectionAlignment);
pSectionHeaderTemp->SizeOfRawData = Align(0x1000, pOptionHeader->FileAlignment);
pSectionHeaderTemp->PointerToRawData = pLastSectionHeaderTemp->PointerToRawData + pLastSectionHeaderTemp->SizeOfRawData;
pSectionHeaderTemp->Characteristics = 0x60000020;
// 修改节表数量
pPEHeader->NumberOfSections++;
// 修改SizeOfImage
pOptionHeader->SizeOfImage += Align(0x1000, pOptionHeader->SectionAlignment);
return FileTotal;
}
BOOL Memory2File(PVOID pNewFileBuffer, DWORD size, PSTR write_path){
FILE *fp;
fp = fopen(write_path, "wb");
if(!fp){
printf("(MemoryToFile)写入失败!\n");
return 0;
}
printf("mtf :%x\n", pNewFileBuffer);
fwrite(pNewFileBuffer, size, 1, fp);
fclose(fp);
return 1;
}
int main(){
PSTR file_path = "C:\\Users\\lolol\\Desktop\\geek2.exe";
PSTR write_path = "D:\\4.exe";
PVOID pFileBuffer = NULL;
PVOID pNewFileBuffer = NULL;
DWORD FileSize = toLordPE(file_path, &pFileBuffer);
printf("文件在磁盘上的大小:%x\n", FileSize);
printf("%x\n",pFileBuffer);
DWORD FileTotal = AddSection(file_path, &pFileBuffer, FileSize, &pNewFileBuffer);
printf("%x\n",FileTotal);
if(FileTotal){
BOOL IsSuccess = Memory2File(pNewFileBuffer, FileTotal, write_path);
if(IsSuccess){
printf("增加成功!\n");
}
}else{
printf("增加失败!\n");
}
// 释放空间
if(pFileBuffer){
free(pFileBuffer);
}
if(pNewFileBuffer){
free(pNewFileBuffer);
}
return 0;
}
PE新增一个节
于 2022-08-31 10:54:21 首次发布