滴水逆向_新增节
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;
}