Last updated on May 5, 2024 am
第一步,遍历节表
首先应当遍历节表,找到最后一节。
尝试在该节后找到一段连续的40字节空间,因为节表中每一项的长度是固定的40字节。
找到这块空间,便于我们操作。
寻找连续空间的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| DWORD FindEmptyAddress(void* start, int maxSize, int codeLen) { int count = 0; int i = 0; while (i <= maxSize - codeLen) { char *current = (char*)start + i; for (int j = 0; j < codeLen; j++) { if (current[j] != 0) { break; } count++; } if (count == codeLen) { return (DWORD)current; } i += count + 1; count = 0; } return 0; }
|
找到连续的空间,确定插入新节的位置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| bool AddSection(lpPEFILE peFile, char* name, int length) { lpPEHPE peHeader = peFile->h_pe; lpPETable table = peFile->pet;
int sections = peHeader->NumberOfSections;
lpPETable newTable = table + sections;
DWORD injectEntry = FindEmptyAddress(newTable, 0x28, 0x28);
if (injectEntry == 0) { return false; }
|
第二步,复制节
先将最后一节复制到我们找到的这40字节空间中。
这样我们只需要在原节表的结构上修改即可。
1 2 3 4
| memcpy(newTable, table + sections - 1, 0x28);
memcpy(newTable->name, name, 8);
|
第三步,修复节表
新节表复制好了,但是其属性内容不太正常,我们需要修复一下(注意,此处要考虑内存对齐问题)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| newTable->PointerToRawData += newTable->SizeOfRawData;
newTable->VirtualAddress += newTable->VirtualSize;
newTable->SizeOfRawData = length;
newTable->VirtualSize = length;
DWORD sectionAlignment = peFile->h_op->SectionAlignment; DWORD alignMod = newTable->VirtualAddress % sectionAlignment; if (alignMod != 0) { newTable->VirtualAddress += (sectionAlignment - alignMod); }
DWORD fileAlignment = peFile->h_op->FileAlignment; alignMod = newTable->PointerToRawData % fileAlignment; if (alignMod != 0) { newTable->PointerToRawData += (fileAlignment - alignMod); }
|
第四步,修复PE头
1 2 3 4
| peFile->h_op->SizeOfImage += length;
peHeader->NumberOfSections += 1;
|
第五步,初始化新节
此处我就全部用0填充了。
1 2
| DWORD imageBase = (DWORD)peFile->h_dos; memset((void*)(imageBase + newTable->PointerToRawData), 0, newTable->SizeOfRawData);
|
完整函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| bool AddSection(lpPEFILE peFile, char* name, int length) { lpPEHPE peHeader = peFile->h_pe; lpPETable table = peFile->pet;
int sections = peHeader->NumberOfSections; lpPETable newTable = table + sections; DWORD injectEntry = FindEmptyAddress(newTable, 0x28, 0x28);
if (injectEntry == 0) { return false; } memcpy(newTable, table + sections - 1, 0x28); memcpy(newTable->name, name, 8);
newTable->PointerToRawData += newTable->SizeOfRawData; newTable->VirtualAddress += newTable->VirtualSize; newTable->SizeOfRawData = length; newTable->VirtualSize = length;
DWORD sectionAlignment = peFile->h_op->SectionAlignment; DWORD alignMod = newTable->VirtualAddress % sectionAlignment; if (alignMod != 0) { newTable->VirtualAddress += (sectionAlignment - alignMod); } DWORD fileAlignment = peFile->h_op->FileAlignment; alignMod = newTable->PointerToRawData % fileAlignment; if (alignMod != 0) { newTable->PointerToRawData += (fileAlignment - alignMod); }
peFile->h_op->SizeOfImage += length; peHeader->NumberOfSections += 1;
DWORD imageBase = (DWORD)peFile->h_dos; memset((void*)(imageBase + newTable->PointerToRawData), 0, newTable->SizeOfRawData); return true; }
|
PE结构(5)新增节
http://dubhehub.github.io/blogs/2024050415400062615.html