逆向 | PE新增节
逆向 | PE 新增节
还是给自己的书写代码,这里顺便存一份:
操作的样本是32位的。
#include <stdio.h>
#include <Windows.h>
#include <string.h>
VOID hex_print(UCHAR* p, DWORD size) {
DWORD i;
printf("\n--------%p--------\n", p);
for (i = 0; i < size; i++) {
printf("0x%02X ", p[i]);
if ((i + 1) % 16 == 0) {
printf("\n");
}
}
printf("\n----------------\n");
}
VOID add_section(WCHAR* pefilename, DWORD section_size) {
// 映射PE文件进内存
printf("add section: [%ls] \n", pefilename);
HANDLE fp = CreateFile(pefilename,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
if (fp == NULL) {
printf("err CreateFile \n");
return;
}
DWORD dwBytesInBlock = GetFileSize(fp, NULL); //文件长度
printf(" > file size: %x \n", dwBytesInBlock);
HANDLE hFileMapping = CreateFileMapping(fp,
NULL,
PAGE_READWRITE,
0,//(DWORD)(dwBytesInBlock >> 16),
dwBytesInBlock,//(DWORD)(dwBytesInBlock & 0x0000FFFF),
NULL);
int dwError = GetLastError();
// 偏移地址
DWORD64 qwFileOffset = 0;
// 将文件数据映射到进程的地址空间
LPVOID pbFile = (LPVOID)MapViewOfFile(hFileMapping,
FILE_MAP_ALL_ACCESS,
(DWORD)(qwFileOffset >> 32),
(DWORD)(qwFileOffset & 0xFFFFFFFF),
dwBytesInBlock);
printf(" > map: %p \n", pbFile);
// 检索PE文件信息
if (((PIMAGE_DOS_HEADER)pbFile)->e_magic != IMAGE_DOS_SIGNATURE) {
printf(" > IMAGE_DOS_SIGNATURE check fail \n");
hex_print((UCHAR*)pbFile, 16);
return;
}
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((DWORD64)pbFile + ((PIMAGE_DOS_HEADER)pbFile)->e_lfanew);
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
printf(" > IMAGE_NT_SIGNATURE check fail \n");
hex_print((UCHAR*)pNtHeader, 16);
return;
}
// 判断是否有足够的空间增加一个节表项
printf(" > NumberOfSections: %d \n", pNtHeader->FileHeader.NumberOfSections);
printf(" > SizeOfHeaders: 0x%x \n", pNtHeader->OptionalHeader.SizeOfHeaders);
if ((pNtHeader->FileHeader.NumberOfSections + 1) * sizeof(IMAGE_SECTION_HEADER) >
(pNtHeader->OptionalHeader.SizeOfHeaders)) {
printf("not enough space for a new section header! \n");
return;
}
// 获取新增节标项的内存位置和文件偏移
PIMAGE_SECTION_HEADER pNewSection = (PIMAGE_SECTION_HEADER)((DWORD64)pNtHeader + 24/*标准PE头size*/ +
pNtHeader->FileHeader.SizeOfOptionalHeader + pNtHeader->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER));
printf("> new section position: 0x%x \n", (DWORD64)pNewSection - (DWORD64)pbFile);
PIMAGE_SECTION_HEADER pLastSection = (PIMAGE_SECTION_HEADER)((DWORD64)pNewSection - 40/*节表项的大小*/);
// 新增一个节表项
memcpy(pNewSection->Name, ".mz", strlen(".mz"));
pNewSection->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_INITIALIZED_DATA; // 设置节属性为可读可写
pNewSection->PointerToRawData = pLastSection->PointerToRawData + pLastSection->SizeOfRawData;// 文件中的节偏移FOA(从最后一个节标项目获取到新增节的文件偏移)
pNewSection->SizeOfRawData = section_size; // 文件中的节大小
pNewSection->Misc.VirtualSize = section_size; // 在内存中的大小
DWORD64 mem_size_last_section = 0;
if (pLastSection->Misc.VirtualSize > pLastSection->SizeOfRawData) {
if (pLastSection->Misc.VirtualSize % 0x1000 != 0) {
mem_size_last_section = (pLastSection->Misc.VirtualSize / 0x1000/*内存对齐大小*/) * 0x1000 + 0x1000;
}
mem_size_last_section = pLastSection->Misc.VirtualSize;
}
else {
mem_size_last_section = pLastSection->SizeOfRawData;
}
pNewSection->VirtualAddress = pLastSection->VirtualAddress + mem_size_last_section;
printf(" > PointerToRawData: %p \n", pNewSection->PointerToRawData);
printf(" > SizeOfRawData: %p \n", pNewSection->SizeOfRawData);
printf(" > VirtualAddress: %p \n", pNewSection->VirtualAddress);
printf(" > VirtualSize: %p \n", pNewSection->Misc.VirtualSize);
// 输出新的节表项目
hex_print((UCHAR*)pNewSection, 40);
// 初始化节数据
VOID* buf = malloc(section_size);
DWORD wsize = 0;
memset(buf, 0, section_size);
SetFilePointer(fp, pNewSection->PointerToRawData, NULL, FILE_BEGIN);
WriteFile(fp, buf, section_size, &wsize, NULL);
// 更新PE头中接的数量和整个imagesize的大小
pNtHeader->FileHeader.NumberOfSections += 1;
pNtHeader->OptionalHeader.SizeOfImage = pNewSection->VirtualAddress + pNewSection->Misc.VirtualSize;
// 释放资源
free(buf);
UnmapViewOfFile(pbFile);
CloseHandle(hFileMapping);
CloseHandle(fp);
}
本文来自博客园,作者:Mz1,转载请注明原文链接:https://www.cnblogs.com/Mz1-rc/p/18306081
如果有问题可以在下方评论或者email:mzi_mzi@163.com