1 本人亲测过了,在win10,win11 下也是可以新增的
2 手动就不演示了, 能够准确地写程序完成新增节并且正常运行。
3 无论是内存对齐,文件对齐 相等还是说不相等都是可以实现的,测试过了。
附上代码:
header.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stddef.h>
#include<Windows.h>#define FILEPATH_IN "D:\\pelianxi\\$RDIZSRI.exe" //自己改路径#define FILEPATH_OUT "D:\\pelianxi\\飞鸽传书新增节.exe" //自己改路径#define ADDRBUFFER 0X1000 //扩充内存大小int READPEFILE_(char* filepath, char** pfilebuffer);//硬盘中新增一个节
int ADDRNEWSECTION_(char* pfilebuffer, char** poutfilebuffer);int FILEBUFFERTOIMAGBBUFFER_(char* pfilebuffer, char** imagebuffer);int IMAGEBUFFERTONEWBUFFER_(char* imagebuffer, char** newbuffer);int WRITEPEFILE_(char* pfilepath, char* pfilebuffer, int filesize);int FREEBUFFER_(char* pfilebuffer);
#include"header.h"int READPEFILE_(char* filepath, char** pfilebuffer)
{FILE* PFILE = NULL;PFILE = fopen(filepath, "rb");if (!PFILE){printf("读取失败\n");return 0;}fseek(PFILE, 0, SEEK_END);int FILESIZE = ftell(PFILE);fseek(PFILE, 0, SEEK_SET);char* PFILETEMPBUFFER = (char*)malloc(sizeof(char) * FILESIZE);if (!PFILETEMPBUFFER){printf("读取失败\n");free(PFILETEMPBUFFER);PFILETEMPBUFFER = NULL;fclose(PFILE);return 0;}memset(PFILETEMPBUFFER, 0, sizeof(char) * FILESIZE);size_t n = fread(PFILETEMPBUFFER, FILESIZE, 1, PFILE);if (!n){printf("失败");free(PFILETEMPBUFFER);PFILETEMPBUFFER = NULL;fclose(PFILE);return 0;}*pfilebuffer = PFILETEMPBUFFER;PFILETEMPBUFFER = NULL;fclose(PFILE);return FILESIZE;
}int ADDRNEWSECTION_(char* pfilebuffer, char** poutfilebuffer)
{if (!pfilebuffer){MessageBox(0, TEXT("缓冲区不存在"), 0, 0);return 0;}if (*(short*)(pfilebuffer) != 0X5A4D){MessageBox(0, TEXT("不是一个mz文件标志"), 0, 0);return 0;}PIMAGE_DOS_HEADER PDOSHEADER = (PIMAGE_DOS_HEADER)pfilebuffer;if (*(PDWORD)((char*)pfilebuffer + PDOSHEADER->e_lfanew) != IMAGE_NT_SIGNATURE){MessageBox(0, TEXT("不是一个NT标记"), 0, 0);return 0;}PIMAGE_NT_HEADERS PNTHEADER = (PIMAGE_NT_HEADERS)((char*)pfilebuffer + PDOSHEADER->e_lfanew);PIMAGE_FILE_HEADER PFILEHEADER = (PIMAGE_FILE_HEADER)(((char*)PNTHEADER) + 0X4);PIMAGE_OPTIONAL_HEADER POPTIONHEADER = (PIMAGE_OPTIONAL_HEADER)(((char*)PFILEHEADER) + 0x14);PIMAGE_SECTION_HEADER PSECTIONHEADER = (PIMAGE_SECTION_HEADER)((char*)POPTIONHEADER + PFILEHEADER->SizeOfOptionalHeader);//判断空间够不够int num = 0x28 * PFILEHEADER->NumberOfSections; if (POPTIONHEADER->SizeOfHeaders - PDOSHEADER->e_lfanew - 0x18 - PFILEHEADER->SizeOfOptionalHeader - num < 2 * 0x28){printf("没有多的空间新增节\n");return 0;}PFILEHEADER->NumberOfSections += 1;POPTIONHEADER->SizeOfImage += ADDRBUFFER;char name[8] = { 'N','e','c','_','S','e','c','\0' };int pnewsec = ((char*)PSECTIONHEADER) + (0X28 * (PFILEHEADER->NumberOfSections - 1));memcpy((char*)pnewsec, &name, 0x8);PIMAGE_SECTION_HEADER pnewsection = (PIMAGE_SECTION_HEADER)pnewsec;pnewsection->SizeOfRawData = ADDRBUFFER;pnewsection->Misc.VirtualSize = ADDRBUFFER;//找到前面这个节,后面一个节需前面一个节 的文件开始的地方 加上 文件对齐以后的数据 pnewsection->PointerToRawData = PSECTIONHEADER[PFILEHEADER->NumberOfSections - 1 - 1].PointerToRawData+ PSECTIONHEADER[PFILEHEADER->NumberOfSections - 1 - 1].SizeOfRawData;pnewsection->VirtualAddress = POPTIONHEADER->SizeOfImage - ADDRBUFFER;//修改可执行属性pnewsection->Characteristics = 0x60000020;//计算硬盘中大小int sizeoffile = PSECTIONHEADER[PFILEHEADER->NumberOfSections - 1 - 1].PointerToRawData + PSECTIONHEADER[PFILEHEADER->NumberOfSections - 1 - 1].SizeOfRawData;char* newbuffer = malloc(sizeof(char) * (sizeoffile + ADDRBUFFER));if (!newbuffer){printf("申请内存失败\n");return 0;}memset((void*)newbuffer, 0, sizeoffile + ADDRBUFFER);memcpy((void*)newbuffer, PDOSHEADER, sizeoffile);*poutfilebuffer = newbuffer;newbuffer = NULL;return sizeoffile;
}int FILEBUFFERTOIMAGBBUFFER_(char* pfilebuffer, char** imagebuffer)
{if (!pfilebuffer){MessageBox(0, TEXT("缓冲区不存在"), 0, 0);return 0;}if (*(short*)(pfilebuffer) != 0X5A4D){MessageBox(0, TEXT("不是一个mz文件标志"), 0, 0);return 0;}PIMAGE_DOS_HEADER PDOSHEADER = (PIMAGE_DOS_HEADER)pfilebuffer;if (*(PDWORD)((char*)pfilebuffer + PDOSHEADER->e_lfanew) != IMAGE_NT_SIGNATURE){MessageBox(0, TEXT("不是一个NT标记"), 0, 0);return 0;}PIMAGE_NT_HEADERS PNTHEADER = (PIMAGE_NT_HEADERS)((char*)pfilebuffer + PDOSHEADER->e_lfanew);PIMAGE_FILE_HEADER PFILEHEADER = (PIMAGE_FILE_HEADER)(((char*)PNTHEADER) + 0X4);PIMAGE_OPTIONAL_HEADER POPTIONHEADER = (PIMAGE_OPTIONAL_HEADER)((char*)PFILEHEADER + 0x14);PIMAGE_SECTION_HEADER PSECTIONHEADER = (PIMAGE_SECTION_HEADER)((char*)POPTIONHEADER + PFILEHEADER->SizeOfOptionalHeader);//固定动态基址PFILEHEADER->Characteristics |= IMAGE_FILE_RELOCS_STRIPPED;char* PIMAGETEMPBUFFER = malloc(sizeof(char) * POPTIONHEADER->SizeOfImage);if (!PIMAGETEMPBUFFER){return 0;}memset(PIMAGETEMPBUFFER, 0, sizeof(char) * POPTIONHEADER->SizeOfImage);memcpy((void*)PIMAGETEMPBUFFER, PDOSHEADER, POPTIONHEADER->SizeOfHeaders);PIMAGE_SECTION_HEADER PTEMPSECTION = (PIMAGE_SECTION_HEADER)PSECTIONHEADER;for (int i = 0; i < PFILEHEADER->NumberOfSections; i++){memcpy((void*)((char*)PIMAGETEMPBUFFER + PTEMPSECTION[i].VirtualAddress),(void*)((char*)PDOSHEADER + PTEMPSECTION[i].PointerToRawData),PTEMPSECTION[i].SizeOfRawData);}*imagebuffer = PIMAGETEMPBUFFER;PIMAGETEMPBUFFER = NULL;return POPTIONHEADER->SizeOfImage;
}int IMAGEBUFFERTONEWBUFFER_(char* pimagebuffer, char** newbuffer)
{if (!pimagebuffer){MessageBox(0, TEXT("缓冲区不存在"), 0, 0);return 0;}if (*(short*)(pimagebuffer) != 0X5A4D){MessageBox(0, TEXT("不是一个mz文件标志"), 0, 0);return 0;}PIMAGE_DOS_HEADER PDOSHEADER = (PIMAGE_DOS_HEADER)pimagebuffer;if (*(PDWORD)((char*)pimagebuffer + PDOSHEADER->e_lfanew) != IMAGE_NT_SIGNATURE){MessageBox(0, TEXT("不是一个NT标记"), 0, 0);return 0;}PIMAGE_NT_HEADERS PNTHEADER = (PIMAGE_NT_HEADERS)((char*)pimagebuffer + PDOSHEADER->e_lfanew);PIMAGE_FILE_HEADER PFILEHEADER = (PIMAGE_FILE_HEADER)(((char*)PNTHEADER) + 0X4);PIMAGE_OPTIONAL_HEADER POPTIONHEADER = (PIMAGE_OPTIONAL_HEADER)((char*)PFILEHEADER + 0x14);PIMAGE_SECTION_HEADER PSECTIONHEADER = (PIMAGE_SECTION_HEADER)((char*)POPTIONHEADER + PFILEHEADER->SizeOfOptionalHeader);char* PTEMPNEWBUFFER = malloc(sizeof(char) * POPTIONHEADER->SizeOfImage);if (!PTEMPNEWBUFFER){return 0;}memset(PTEMPNEWBUFFER, 0, sizeof(char) * POPTIONHEADER->SizeOfImage);memcpy((void*)PTEMPNEWBUFFER, PDOSHEADER, POPTIONHEADER->SizeOfHeaders);PIMAGE_SECTION_HEADER PTEMPSECTION = (PIMAGE_SECTION_HEADER)PSECTIONHEADER;for (int i = 0; i < PFILEHEADER->NumberOfSections; i++){memcpy((void*)((char*)PTEMPNEWBUFFER + PTEMPSECTION[i].PointerToRawData),(void*)((char*)pimagebuffer + PTEMPSECTION[i].VirtualAddress),PTEMPSECTION[i].SizeOfRawData);}*newbuffer = PTEMPNEWBUFFER;PTEMPNEWBUFFER = NULL;return POPTIONHEADER->SizeOfImage;
}int WRITEPEFILE_(char* pfilepath, char* pfilebuffer, int filesize)
{FILE* PFILE = NULL;PFILE = fopen(pfilepath, "wb");if (!PFILE){return 0;}size_t n = fwrite(pfilebuffer, filesize, 1, PFILE);if (!n){fclose(PFILE);return 0;}fclose(PFILE);return 1;
}int FREEBUFFER_(char* pfilebuffer)
{if (!pfilebuffer){return 0;}else{free(pfilebuffer);pfilebuffer = NULL;}}
#include"header.h"char* pfilebuffer = NULL;char* pimagebuffer = NULL;char* paddrfilebuffer = NULL;char* newbuffer = NULL;int main()
{READPEFILE_(FILEPATH_IN, &pfilebuffer);ADDRNEWSECTION_(pfilebuffer, &paddrfilebuffer);FILEBUFFERTOIMAGBBUFFER_(paddrfilebuffer, &pimagebuffer);int filesize = IMAGEBUFFERTONEWBUFFER_(pimagebuffer, &newbuffer);WRITEPEFILE_(FILEPATH_OUT, newbuffer, filesize);system("pause");return 0;
}