添加节

    科技2022-07-10  190

    文章目录

    一、流程二、演示三、完整代码四、勿在浮沙筑高台

    一、流程

    1、File-> FileBuffer 2、FileBuffer->ImageBuffer 3、判断空闲区是否有足够的空间存储ShellCode代码 4、将NT头到节表往上提 5、新增一个节表 6、添加属性 7、将修改后的数据复制到一个新的缓冲区中去(pNewImageBuffer) 8、将ShellCode代码复制到空闲区 9、修正E8、E9 10、修正OEP(入口程序) 11、pNewImageBuffer->NewBuffer 12、NewBuffer->文件

    二、演示

    1、(看,读取->拉伸->还原,篇) 2、(看,读取->拉伸->还原,篇) 3、判断空闲区是否有足够的空间存储ShellCode代码

    //DOS头地址 pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer; //NT头地址 pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pImageBuffer + pDosHeader->e_lfanew); //标准PE头地址 pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 0x4); //可选PE头地址 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER); //第一个节表地址 pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader); if((DWORD)pNTHeader - (DWORD)(pDosHeader->e_lfanew) < sizeof(IMAGE_SECTION_HEADER)) { printf("没有多余空间"); free(pFileBuffer); return; }

    4、将NT头到节表往上提

    memcpy((void*)((DWORD)pDosHeader + 0x40), pNTHeader, (DWORD)(pSectionHeader + pPEHeader->NumberOfSections) - (DWORD)pNTHeader);

    5、新增一个节表

    pDosHeader->e_lfanew = 0x40; //DOS头地址 pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer; //NT头地址 pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pImageBuffer + pDosHeader->e_lfanew); //标准PE头地址 pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 0x4); //可选PE头地址 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER); //第一个节表地址 pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader); //添加一个新的节表 memcpy((void*)(DWORD)(pSectionHeader + pPEHeader->NumberOfSections),(const void *)(DWORD)pSectionHeader,sizeof(PIMAGE_SECTION_HEADER)); //修改PE头中的节表数量 pPEHeader->NumberOfSections = pPEHeader->NumberOfSections + 1;

    6、添加属性

    //修改新增节表的属性 char* s = ".tttt"; memcpy((pSectionHeader + pPEHeader->NumberOfSections - 1)->Name,s,strlen(s) + 1); (pSectionHeader + pPEHeader->NumberOfSections - 1)->Misc.VirtualSize = pOptionHeader->SectionAlignment; (pSectionHeader + pPEHeader->NumberOfSections - 1)->VirtualAddress = pOptionHeader->SizeOfImage; (pSectionHeader + pPEHeader->NumberOfSections - 1)->SizeOfRawData = pOptionHeader->SectionAlignment; (pSectionHeader + pPEHeader->NumberOfSections - 1)->PointerToRawData = Size; (pSectionHeader + pPEHeader->NumberOfSections - 1)->Characteristics = 0x60000020; //修改SizeOfImage的大小 pOptionHeader->SizeOfImage = pOptionHeader->SizeOfImage + pOptionHeader->SectionAlignment;

    7、将修改后的数据复制到一个新的缓冲区中去

    //在原有数据的最后,新增一个节的数据(内存对齐的整数倍) pNewImageBuffer = malloc(pOptionHeader->SizeOfImage); memset(pNewImageBuffer,0,pOptionHeader->SizeOfImage); memcpy(pNewImageBuffer,pImageBuffer,pOptionHeader->SizeOfImage - pOptionHeader->SectionAlignment);

    8、将ShellCode代码复制到空闲区

    //DOS头地址 pDosHeader = (PIMAGE_DOS_HEADER)pNewImageBuffer; //NT头地址 pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pNewImageBuffer + pDosHeader->e_lfanew); //标准PE头地址 pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 0x4); //可选PE头地址 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER); //第一个节表地址 pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader); //将代码复制到空闲区 CodeBegin = (PBYTE)((DWORD)pNewImageBuffer + (DWORD)(pSectionHeader + pPEHeader->NumberOfSections - 1)->VirtualAddress); memcpy(CodeBegin,ShellCode,SHELLCODELENGTH);

    9、修正E8、E9

    //修正E8 DWORD CallAddr = (MESSAGEBOXADDR - (pOptionHeader->ImageBase + ((DWORD)(CodeBegin + 0xD) - (DWORD)pNewImageBuffer))); *(PDWORD)(CodeBegin + 9) = CallAddr; //修正E9 DWORD JmpAddr = (pOptionHeader->ImageBase + pOptionHeader->AddressOfEntryPoint) - (pOptionHeader->ImageBase + (pSectionHeader + pPEHeader->NumberOfSections - 1)->VirtualAddress + SHELLCODELENGTH); *(PDWORD)(CodeBegin + 0xE) = JmpAddr;

    10、修正OEP(入口程序)

    //修改OEP pOptionHeader->AddressOfEntryPoint = (DWORD)CodeBegin - (DWORD)pNewImageBuffer;

    11、pNewImageBuffer->NewBuffer(看,读取->拉伸->还原,篇)

    12、NewBuffer->文件(看,读取->拉伸->还原,篇)

    三、完整代码

    #include "stdafx.h" #include <windows.h> #include "stdlib.h" #include "stdio.h" #define FILEPATH_IN "C:/fg.exe" #define FILEPATH_OUT "C:/copyxx.exe" #define SHELLCODELENGTH 0x12 #define MESSAGEBOXADDR 0x77D5050B BYTE ShellCode[] = { 0x6A,00,0x6A,00,0x6A,00,0x6A,00, 0xE8,00,00,00,00, 0xE9,00,00,00,00 }; DWORD ReadPEFile(IN LPSTR lpszFile,OUT LPVOID* pFileBuffer ) { FILE *pFile = NULL; DWORD fileSize = 0; //文件大小 LPVOID pTempFileBuffer = NULL; //缓冲区首地址 pFile = fopen(lpszFile,"rb"); //打开文件 if(!pFile) { printf("打开文件失败"); return NULL; } //读取文件大小 fseek(pFile,0,SEEK_END); //将指针从开始的位置移动到末尾 fileSize = ftell(pFile); //获取数据大小 //分配缓冲区(申请内存) pTempFileBuffer = malloc(fileSize); if(!pTempFileBuffer) { printf("分配空间失败"); fclose(pFile); return NULL; } //将文件数据读取到缓冲区 fseek(pFile,0,SEEK_SET); //将指针指向开始 size_t n = fread(pTempFileBuffer,fileSize,1,pFile); //将数据读取到缓冲区中 if(!n) { printf("读取数据失败"); free(pTempFileBuffer); //释放内存 fclose(pFile); //关闭文件 return NULL; } //关闭文件 *pFileBuffer = pTempFileBuffer; pTempFileBuffer = NULL; fclose(pFile); //关闭文件 return fileSize; } DWORD CopyFileBufferToImageBuffer(IN LPVOID pFileBuffer,OUT LPVOID* pImageBuffer) { PIMAGE_DOS_HEADER pDosHeader = NULL; //用来接收DOS头信息 PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pPEHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL; LPVOID pTemImageBuffer = NULL; //判断传入的值是否有效 if(!pFileBuffer) { printf("缓冲区指针无效"); return 0; } //判断是否为PE文件 if(*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE) { printf("不是有效的MZ头\n"); return 0; } //获取头信息 pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; if(*((PDWORD)((DWORD)pFileBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE) { printf("不是有效的PE标志\n"); return 0; } //NT头地址 pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew); //标准PE头地址 pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 0x4); //可选PE头地址 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER); //第一个节表地址 pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader); //申请缓冲区大小 pTemImageBuffer = malloc(pOptionHeader->SizeOfImage); if(!pTemImageBuffer) { printf("分配空间失败"); return 0; } //初始化缓冲区 memset(pTemImageBuffer,0,pOptionHeader->SizeOfImage); //根据 SizeOfHeaders,先拷贝头 memcpy(pTemImageBuffer,pDosHeader,pOptionHeader->SizeOfHeaders); //根据节表,循环拷贝节 PIMAGE_SECTION_HEADER pTempSectionHeader = pSectionHeader; for(int i=0;i<pPEHeader->NumberOfSections;i++,pTempSectionHeader++) { memcpy((void*)((DWORD)pTemImageBuffer + pTempSectionHeader->VirtualAddress),(void*)((DWORD)pFileBuffer + pTempSectionHeader->PointerToRawData),pTempSectionHeader->SizeOfRawData); } //返回数据 *pImageBuffer = pTemImageBuffer; pTemImageBuffer = NULL; return 0; } DWORD CopyImageBufferToNewBuffer(IN LPVOID pImageBuffer,OUT LPVOID* pNewBuffer) { 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; LPVOID pTempNewBuffer = NULL; if(!pImageBuffer) { printf("缓冲区指针无效"); return 0; } if(*((PWORD)pImageBuffer) != IMAGE_DOS_SIGNATURE) { printf("不是有效的MZ头\n"); return 0; } pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer; if(*((PDWORD)((DWORD)pImageBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE) { printf("不是有效的PE标志\n"); return 0; } //NT头地址 pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pImageBuffer + pDosHeader->e_lfanew); //标准PE头地址 pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 0x4); //可选PE头地址 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER); //第一个节表地址 pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader); //数据大小(最后一个节的文件偏移 + 最后一个节的真实大小 + 文件对齐) DWORD FileSize = ( (pSectionHeader + pPEHeader->NumberOfSections-1)->PointerToRawData + (pSectionHeader + pPEHeader->NumberOfSections-1)->Misc.VirtualSize + pOptionHeader->FileAlignment )&(0 - pOptionHeader->FileAlignment); pTempNewBuffer = malloc(FileSize); if(!pTempNewBuffer) { printf("分配空间失败"); return 0; } //初始化缓冲区 memset(pTempNewBuffer,0,FileSize); memcpy(pTempNewBuffer,pDosHeader,pOptionHeader->SizeOfHeaders); //根据节表,循环拷贝节 PIMAGE_SECTION_HEADER pTempSectionHeader = pSectionHeader; for(int i=0;i<pPEHeader->NumberOfSections;i++,pTempSectionHeader++) { memcpy((void*)((DWORD)pTempNewBuffer + pTempSectionHeader->PointerToRawData), (void*)((DWORD)pImageBuffer + pTempSectionHeader->VirtualAddress), pTempSectionHeader->Misc.VirtualSize); } *pNewBuffer = pTempNewBuffer; pTempNewBuffer = NULL; return FileSize; } BOOL MemeryTOFile(LPVOID pMemBuffer,size_t size,LPSTR lpszFile) { FILE *fp = NULL; fp = fopen(lpszFile,"wb"); if(!fp) { return FALSE; } fwrite(pMemBuffer,size,1,fp); //向磁盘写入数据 fclose(fp); //关闭文件 fp = NULL; return TRUE; } VOID Test() { DWORD Size = 0; //用来接收数据大小 BOOL isok = FALSE; //用来接收写入磁盘是否成功 PBYTE CodeBegin = NULL; LPVOID pFileBuffer = NULL; //用来接收缓冲区的首地址 LPVOID pImageBuffer = NULL; LPVOID pNewBuffer = NULL; LPVOID pNewImageBuffer = NULL; 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; //File-> FileBuffer Size = ReadPEFile(FILEPATH_IN,&pFileBuffer); //调用函数读取文件数据 if(!pFileBuffer || !Size) { printf("File-> FileBuffer失败"); return; } //FileBuffer->ImageBuffer CopyFileBufferToImageBuffer(pFileBuffer,&pImageBuffer); if(!pImageBuffer) { printf("FileBuffer->ImageBuffer失败"); free(pFileBuffer); return; } //DOS头地址 pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer; //NT头地址 pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pImageBuffer + pDosHeader->e_lfanew); //标准PE头地址 pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 0x4); //可选PE头地址 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER); //第一个节表地址 pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader); if((DWORD)pNTHeader - (DWORD)(pDosHeader->e_lfanew) < sizeof(IMAGE_SECTION_HEADER)) { printf("没有多余空间"); free(pFileBuffer); return; } memcpy((void*)((DWORD)pDosHeader + 0x40),pNTHeader,(DWORD)(pSectionHeader + pPEHeader->NumberOfSections) - (DWORD)pNTHeader); pDosHeader->e_lfanew = 0x40; //DOS头地址 pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer; //NT头地址 pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pImageBuffer + pDosHeader->e_lfanew); //标准PE头地址 pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 0x4); //可选PE头地址 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER); //第一个节表地址 pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader); //添加一个新的节表 memcpy((void*)(DWORD)(pSectionHeader + pPEHeader->NumberOfSections),(const void *)(DWORD)pSectionHeader,sizeof(PIMAGE_SECTION_HEADER)); //修改PE头中的节表数量 pPEHeader->NumberOfSections = pPEHeader->NumberOfSections + 1; //修改新增节表的属性 char* s = ".tttt"; memcpy((pSectionHeader + pPEHeader->NumberOfSections - 1)->Name,s,strlen(s) + 1); (pSectionHeader + pPEHeader->NumberOfSections - 1)->Misc.VirtualSize = pOptionHeader->SectionAlignment; (pSectionHeader + pPEHeader->NumberOfSections - 1)->VirtualAddress = pOptionHeader->SizeOfImage; (pSectionHeader + pPEHeader->NumberOfSections - 1)->SizeOfRawData = pOptionHeader->SectionAlignment; (pSectionHeader + pPEHeader->NumberOfSections - 1)->PointerToRawData = Size; (pSectionHeader + pPEHeader->NumberOfSections - 1)->Characteristics = 0x60000020; //修改SizeOfImage的大小 pOptionHeader->SizeOfImage = pOptionHeader->SizeOfImage + pOptionHeader->SectionAlignment; //在原有数据的最后,新增一个节的数据(内存对齐的整数倍) pNewImageBuffer = malloc(pOptionHeader->SizeOfImage); memset(pNewImageBuffer,0,pOptionHeader->SizeOfImage); memcpy(pNewImageBuffer,pImageBuffer,pOptionHeader->SizeOfImage - pOptionHeader->SectionAlignment); //DOS头地址 pDosHeader = (PIMAGE_DOS_HEADER)pNewImageBuffer; //NT头地址 pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pNewImageBuffer + pDosHeader->e_lfanew); //标准PE头地址 pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 0x4); //可选PE头地址 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER); //第一个节表地址 pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader); //将代码复制到空闲区 CodeBegin = (PBYTE)((DWORD)pNewImageBuffer + (DWORD)(pSectionHeader + pPEHeader->NumberOfSections - 1)->VirtualAddress); memcpy(CodeBegin,ShellCode,SHELLCODELENGTH); //修正E8 DWORD CallAddr = (MESSAGEBOXADDR - (pOptionHeader->ImageBase + ((DWORD)(CodeBegin + 0xD) - (DWORD)pNewImageBuffer))); *(PDWORD)(CodeBegin + 9) = CallAddr; //修正E9 DWORD JmpAddr = (pOptionHeader->ImageBase + pOptionHeader->AddressOfEntryPoint) - (pOptionHeader->ImageBase + (pSectionHeader + pPEHeader->NumberOfSections - 1)->VirtualAddress + SHELLCODELENGTH); *(PDWORD)(CodeBegin + 0xE) = JmpAddr; //修改OEP pOptionHeader->AddressOfEntryPoint = (DWORD)CodeBegin - (DWORD)pNewImageBuffer; //pNewImageBuffer->NewBuffer Size = CopyImageBufferToNewBuffer(pNewImageBuffer,&pNewBuffer); if(!Size || !pNewBuffer) { printf("ImageBuffer->NewBuffer失败"); free(pFileBuffer); free(pImageBuffer); return; } //NewBuffer->文件 isok = MemeryTOFile(pNewBuffer,Size,FILEPATH_OUT); if(isok) { printf("存盘成功"); return; } //释放内存 free(pFileBuffer); free(pImageBuffer); free(pNewBuffer); } int main(int argc, char* argv[]) { Test(); getchar(); return 0; }

    不拉伸 添加

    #include "stdafx.h" #include <windows.h> #include "stdlib.h" #define FILEPATH_IN "C:/notepad.exe" DWORD ReadPEFile(IN LPSTR lpszFile,OUT LPVOID* pFileBuffer ) { FILE *pFile = NULL; DWORD fileSize = 0; //文件大小 LPVOID pTempFileBuffer = NULL; //缓冲区首地址 pFile = fopen(lpszFile,"rb"); //打开文件 if(!pFile) { printf("打开文件失败"); return NULL; } //读取文件大小 fseek(pFile,0,SEEK_END); //将指针从开始的位置移动到末尾 fileSize = ftell(pFile); //获取数据大小 //分配缓冲区(申请内存) pTempFileBuffer = malloc(fileSize); if(!pTempFileBuffer) { printf("分配空间失败"); fclose(pFile); return NULL; } //将文件数据读取到缓冲区 fseek(pFile,0,SEEK_SET); //将指针指向开始 size_t n = fread(pTempFileBuffer,fileSize,1,pFile); //将数据读取到缓冲区中 if(!n) { printf("读取数据失败"); free(pTempFileBuffer); //释放内存 fclose(pFile); //关闭文件 return NULL; } //关闭文件 *pFileBuffer = pTempFileBuffer; pTempFileBuffer = NULL; fclose(pFile); //关闭文件 return fileSize; } //********************************************************************** BOOL MemeryTOFile(LPVOID pMemBuffer,size_t size) { FILE *fp = NULL; fp = fopen("C:/copyxx1.exe","wb"); if(!fp) { return FALSE; } fwrite(pMemBuffer,size,1,fp); //向磁盘写入数据 fclose(fp); //关闭文件 fp = NULL; return TRUE; } //********************************************************************** BOOL AddSection() { DWORD Size = 0; //用来接收数据大小 BOOL isok = FALSE; //用来接收写入磁盘是否成功 LPVOID pFileBuffer = NULL; PIMAGE_DOS_HEADER pDosHeader = NULL; //用来接收DOS头信息 PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pPEHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL; PIMAGE_SECTION_HEADER pNewSec = NULL; //新节表结构 //File-> FileBuffer Size = ReadPEFile(FILEPATH_IN,&pFileBuffer); //调用函数读取文件数据 if(!pFileBuffer || !Size) { printf("File-> FileBuffer失败"); return FALSE; } //DOS头地址 pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; //NT头地址 pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew); //标准PE头地址 pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 0x4); //可选PE头地址 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER); //第一个节表地址 pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader); if((DWORD)pNTHeader - (DWORD)(pDosHeader->e_lfanew) < sizeof(IMAGE_SECTION_HEADER)) { printf("没有多余空间"); free(pFileBuffer); return FALSE; } memcpy((void*)((DWORD)pDosHeader + 0x40), pNTHeader, (DWORD)(pSectionHeader + pPEHeader->NumberOfSections) - (DWORD)pNTHeader); pDosHeader->e_lfanew = 0x40; //DOS头地址 pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; //NT头地址 pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew); //标准PE头地址 pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 0x4); //可选PE头地址 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER); //第一个节表地址 pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader); //新增节表结构 pNewSec = (PIMAGE_SECTION_HEADER)(pSectionHeader + pPEHeader->NumberOfSections); //修改节表内容 memcpy(pNewSec->Name,".export",8);//修改节表名 PIMAGE_SECTION_HEADER upSecHeader = (PIMAGE_SECTION_HEADER)(pSectionHeader + pPEHeader->NumberOfSections-1); if(upSecHeader->Misc.VirtualSize > upSecHeader->SizeOfRawData) //修改节表VrituallAddress { pNewSec->VirtualAddress = upSecHeader->VirtualAddress + upSecHeader->Misc.VirtualSize; }else{ pNewSec->VirtualAddress = upSecHeader->VirtualAddress + upSecHeader->SizeOfRawData; } pNewSec->SizeOfRawData = 0x1000;//新增的节区的大小 pNewSec->Misc.VirtualSize = 0x1000; pNewSec->PointerToRawData = upSecHeader->PointerToRawData + upSecHeader->SizeOfRawData;//文件中的偏移 pNewSec->Characteristics = 0x60000020;//修改属性(可执行) //在新增节表后增加40个字节的空白区 memset(pNewSec+1, 0, 40); pPEHeader->NumberOfSections += 1;//修改NumberOfSection数量 pOptionHeader->SizeOfImage += 0x1000;//修改SizeOfImage大小 isok = MemeryTOFile(pFileBuffer,Size+0x1000); if(isok) { printf("存盘成功"); return true; } //释放内存 free(pFileBuffer); } //********************************************************************** int main(int argc, char* argv[]) { AddSection(); getchar(); return 0; }

    四、勿在浮沙筑高台

    Processed: 0.015, SQL: 8