上节课讲到任意节添加ShellCode,这节课海哥让我们新增一个节,为什么要新增一个节呢?直接在后面添加不好吗,因为节的空间不够大,我们需要从新增加一个节。
需要的知识点:
1.我们需要看是否有足够的空间增加一个节表,一个节表40个字节,但是我们要判断剩余的空间是否为80个字节,因为规定最后一个节表后面需要跟着40空字节,代表结束。
2.需要修改的属性
1) 添加一个新的节表(可以copy .text)
2) 修改标准PE头的NumberOfSection
3) 修改sizeOfImage
3.我们怎么修改新的节表的属性
1)VirtualSize的修正:跟内存对齐相等即可,内存对齐的倍数就行
2)VirtualAddress的修正:看上一个节表的属性,如果文件对齐和内存对齐相等,就等于上一个节的VirtualAdress+RawSize,如果文件和内存对齐不相等,就等于上一个节的VirtualAdress+RawSize(内存对齐后的大小)
3)SizeOfRaw的修正:和VirtualSize一样即可
4)PointToRawData的修正:上一个节的PointToRawData+SizeOfRaw
4.写代码的时候要注意节表的遍历,清楚这是第几个节表,增加完没有?
5.文件对齐和内存对齐不一样的时候,我们可以做一个循环,让他累加,直到内存对齐的倍数
代码:
#include "stdafx.h" #include#include #include #define ShellCodeIen 0x12 #define MessageBoxAdder 0x77D507EA BYTE ShellCode[]= { 0x6A,00,0x6A,00,0x6A,00,0x6A,00, 0xE8,00,00,00,00, 0xE9,00,00,00,00 }; // //FileBuffer函数 DWORD ReadPEFile(LPVOID* ppFileBuffer) { FILE* pFile=NULL; DWORD SizeFileBuffer=0; pFile=fopen("C://documents and Settings//ma_lic//桌面//IISPutScanner.exe","rb"); if(!pFile) { printf("打开notepad失败n"); return 0; } //获取文件大小 fseek(pFile,0,SEEK_END); SizeFileBuffer=ftell(pFile); fseek(pFile,0,SEEK_SET); if(!SizeFileBuffer) { printf("读取文件大小失败n"); return 0; } //开辟空间 *ppFileBuffer=malloc(SizeFileBuffer); if(!*ppFileBuffer) { printf("开辟空间失败n"); fclose(pFile); return 0; } //复制数据 size_t n=fread(*ppFileBuffer,SizeFileBuffer,1,pFile); if(!n) { printf("复制数据失败n"); free(*ppFileBuffer); fclose(pFile); return 0; } fclose(pFile); return SizeFileBuffer; } /// //FileBuffer--->ImgaeBuffer DWORD FileBufferToImageBuffer(LPVOID pFileBuffer,LPVOID* ppImageBuffer) { PIMAGE_DOS_HEADER pDosHeader=NULL; PIMAGE_NT_HEADERS pNTHeader=NULL; PIMAGE_FILE_HEADER pFileHeader=NULL; PIMAGE_OPTIONAL_HEADER pOptionalHeader=NULL; PIMAGE_SECTION_HEADER pSectionHeader=NULL; if(!pFileBuffer) { printf("FileBuffer函数调用失败n"); return 0; } printf("%xn",pFileBuffer); //判断是否是PE文件 pDosHeader=(PIMAGE_DOS_HEADER)pFileBuffer; if(pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE) { printf("不是有效的MZ标志n"); return 0; } pNTHeader=(PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew); if(pNTHeader->Signature!=IMAGE_NT_SIGNATURE) { printf("不是有效的PE标志n"); return 0; } pFileHeader=(PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4); pOptionalHeader=(PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader+20); //开辟ImageBuffer空间 *ppImageBuffer=malloc(pOptionalHeader->SizeOfImage+pOptionalHeader->SectionAlignment);//增加节才加上SectionAligement if(!*ppImageBuffer) { printf("开辟ImageBuffer空间失败"); return 0; } printf("SizeOfImage%xn",pOptionalHeader->SizeOfImage); //malloc清零 memset(*ppImageBuffer,0,pOptionalHeader->SizeOfImage); //复制Headers printf("SizeOfHeader%xn",pOptionalHeader->SizeOfHeaders); memcpy(*ppImageBuffer,pDosHeader,pOptionalHeader->SizeOfHeaders); //循环复制节表 pSectionHeader=(PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader+pFileHeader->SizeOfOptionalHeader); for(int i=1;i<=pFileHeader->NumberOfSections;i++,pSectionHeader++) { memcpy((LPVOID)((DWORD)*ppImageBuffer+pSectionHeader->VirtualAddress),(LPVOID)((DWORD)pFileBuffer+pSectionHeader->PointerToRawData),pSectionHeader->SizeOfRawData); printf("%dn",i); } printf("拷贝完成n"); return pOptionalHeader->SizeOfImage; } //AddSection // LPVOID AddSection(LPVOID pImageBuffer) { if(!pImageBuffer) { printf("pImageBuffer参数传入失败n"); return 0; } PIMAGE_DOS_HEADER pDosHeader=NULL; PIMAGE_NT_HEADERS pNTHeader=NULL; PIMAGE_FILE_HEADER pFileHeader=NULL; PIMAGE_OPTIONAL_HEADER pOptionalHeader=NULL; PIMAGE_SECTION_HEADER pSectionHeader=NULL; PIMAGE_SECTION_HEADER pNewSectionTable=NULL; pDosHeader=(PIMAGE_DOS_HEADER)pImageBuffer; pNTHeader=(PIMAGE_NT_HEADERS)((DWORD)pImageBuffer+pDosHeader->e_lfanew); pFileHeader=(PIMAGE_FILE_HEADER)((DWORD)pNTHeader+4); pOptionalHeader=(PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader+20); pSectionHeader=(PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader+pFileHeader->SizeOfOptionalHeader); //判断文件对齐和内存对齐 if(pOptionalHeader->FileAlignment==pOptionalHeader->SectionAlignment) { printf("文件对齐和内存对齐相等n"); // 判断是否有足够的空间新增节表 DWORD SizeOfSectionTable=0x28; DWORD Freebase=((DWORD)pOptionalHeader->SizeOfHeaders-((DWORD)pSectionHeader+pFileHeader->NumberOfSections*SizeOfSectionTable-(DWORD)pImageBuffer)); if(Freebase NumberOfSections=pFileHeader->NumberOfSections+1; printf("NumberOfSection=%dn",pFileHeader->NumberOfSections); //修改SizeOfImage printf("SizeOfImage=%xn",pOptionalHeader->SizeOfImage); pOptionalHeader->SizeOfImage=pOptionalHeader->SizeOfImage+pOptionalHeader->SectionAlignment; printf("SizeOfImage=%xn",pOptionalHeader->SizeOfImage); //这里就不同扩大ImageBuffer了,上面已经增加了 //填写新的节表(复制.txt节表然后再修正) pNewSectionTable=(PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pFileHeader->NumberOfSections-1)*SizeOfSectionTable); //开始复制.text memcpy(pNewSectionTable,pSectionHeader,SizeOfSectionTable); //修正新的节表 //循环到倒数第二个节表 for(int i=1;i NumberOfSections-1;i++,pSectionHeader++) { printf("%dn",i); } pNewSectionTable->Misc.VirtualSize=pOptionalHeader->SectionAlignment; printf("%xn",pNewSectionTable->Misc.VirtualSize); pNewSectionTable->VirtualAddress=pSectionHeader->VirtualAddress+pSectionHeader->SizeOfRawData; printf("%xn",pNewSectionTable->VirtualAddress); pNewSectionTable->SizeOfRawData=pOptionalHeader->SectionAlignment; printf("%xn",pNewSectionTable->SizeOfRawData); pNewSectionTable->PointerToRawData=pSectionHeader->PointerToRawData+pSectionHeader->SizeOfRawData; printf("%xn",pNewSectionTable->PointerToRawData); printf("新的节表修正完成!!!n"); return pImageBuffer; } else { printf("内存对齐和文件对齐不相等n"); printf("文件对齐和内存对齐相等n"); // 判断是否有足够的空间新增节表 DWORD SizeOfSectionTable=0x28; DWORD Freebase=((DWORD)pOptionalHeader->SizeOfHeaders-((DWORD)pSectionHeader+pFileHeader->NumberOfSections*SizeOfSectionTable-(DWORD)pImageBuffer)); if(Freebase NumberOfSections=pFileHeader->NumberOfSections+1; printf("NumberOfSection=%dn",pFileHeader->NumberOfSections); //修改SizeOfImage printf("SizeOfImage=%xn",pOptionalHeader->SizeOfImage); pOptionalHeader->SizeOfImage=pOptionalHeader->SizeOfImage+pOptionalHeader->SectionAlignment; printf("SizeOfImage=%xn",pOptionalHeader->SizeOfImage); //这里就不用扩大ImageBuffer了,上面已经增加了 //填写新的节表(复制.txt节表然后再修正) pNewSectionTable=(PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pFileHeader->NumberOfSections-1)*SizeOfSectionTable); //开始复制.text memcpy(pNewSectionTable,pSectionHeader,SizeOfSectionTable); //修正新的节表 //循环到倒数第二个节表 for(int i=1;i NumberOfSections-1;i++,pSectionHeader++) { printf("%dn",i); } pNewSectionTable->Misc.VirtualSize=pOptionalHeader->SectionAlignment; printf("%xn",pNewSectionTable->Misc.VirtualSize); DWORD RawSize=pSectionHeader->SizeOfRawData; printf("%x????n",RawSize); //这里因为文件对齐和内存对齐不一样,所以需要对齐 while(RawSize%pOptionalHeader->SectionAlignment!=0) { RawSize++; //printf("RawSize=%xn",RawSize); } pNewSectionTable->VirtualAddress=pSectionHeader->VirtualAddress+RawSize; printf("%xn",pNewSectionTable->VirtualAddress); pNewSectionTable->SizeOfRawData=pOptionalHeader->SectionAlignment; printf("%xn",pNewSectionTable->SizeOfRawData); pNewSectionTable->PointerToRawData=pSectionHeader->PointerToRawData+pSectionHeader->SizeOfRawData; printf("%xn",pNewSectionTable->PointerToRawData); printf("新的节表修正完成!!!n"); return pImageBuffer; } } / //ImageBufferToFileBuffer DWORD ImageBufferToFileBuffer(LPVOID pImageBuffer,LPVOID* ppBuffer) { PIMAGE_DOS_HEADER pDosHeader=NULL; PIMAGE_NT_HEADERS pNTHeader=NULL; PIMAGE_FILE_HEADER pFileHeader=NULL; PIMAGE_OPTIONAL_HEADER pOptionalHeader=NULL; PIMAGE_SECTION_HEADER pSectionHeader=NULL; if(!pImageBuffer) { printf("error"); return 0; } pDosHeader=(PIMAGE_DOS_HEADER)pImageBuffer; pNTHeader=(PIMAGE_NT_HEADERS)((DWORD)pImageBuffer+pDosHeader->e_lfanew); pFileHeader=(PIMAGE_FILE_HEADER)((DWORD)pNTHeader+4); pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + 20); pSectionHeader=(PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader+pFileHeader->SizeOfOptionalHeader); //得到FileBuffer的大小 for(int i=1;i NumberOfSections;i++,pSectionHeader++) { printf("%dn",i); } printf("numberofsection=%dn",pFileHeader->NumberOfSections); printf("%xn",pSectionHeader->Misc.VirtualSize); printf("%xn",pSectionHeader->VirtualAddress); printf("%xn",pSectionHeader->SizeOfRawData); printf("%xn",pSectionHeader->PointerToRawData); //循环到最后一个节表 DWORD SizeOfBuffer=pSectionHeader->PointerToRawData+pSectionHeader->SizeOfRawData; printf("SizeOfBuffer=%xn",SizeOfBuffer); //开辟空间 *ppBuffer=malloc(SizeOfBuffer); if(!*ppBuffer) { printf("开辟Buffer空间失败n"); return 0; } memset(*ppBuffer,0,SizeOfBuffer); //复制头 memcpy(*ppBuffer,pImageBuffer,pOptionalHeader->SizeOfHeaders); //复制节表 pSectionHeader=(PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader+pFileHeader->SizeOfOptionalHeader); printf("wocn"); for(int j=1;j<=pFileHeader->NumberOfSections;j++,pSectionHeader++) { printf("%dn",j); memcpy((LPVOID)((DWORD)*ppBuffer+pSectionHeader->PointerToRawData),(LPVOID)((DWORD)pImageBuffer+pSectionHeader->VirtualAddress),pSectionHeader->SizeOfRawData); } printf("拷贝完成n"); return SizeOfBuffer; } / //存贮到新的exe BOOL MemeryToFile(LPVOID pBuffer,DWORD SizeOfBuffer) { FILE* fpw=fopen("C://documents and Settings//ma_lic//桌面//NEWSECIISPutScanner.exe","wb"); if(!fpw) { printf("fpw error"); return false; } if (fwrite(pBuffer, 1, SizeOfBuffer, fpw) == 0) { printf("fpw fwrite fail"); return false; } fclose(fpw); fpw = NULL; printf("successn"); return true; } int main() { LPVOID pFileBuffer=NULL; LPVOID* ppFileBuffer=&pFileBuffer; LPVOID pImageBuffer=NULL; LPVOID* ppImageBuffer=&pImageBuffer; DWORD SizeOfFileBuffer=0; DWORD SizeOfImageBuffer=0; DWORD SizeOfBuffer=0; LPVOID pBuffer=NULL; LPVOID* ppBuffer=&pBuffer; //调用filebuffer函数 SizeOfFileBuffer=ReadPEFile(ppFileBuffer); if(!SizeOfFileBuffer) { printf("FileBuffer函数调用失败 n"); return 0; } pFileBuffer=*ppFileBuffer; printf("ni ma de"); //调用FileBufferToImageBuffer函数 SizeOfBuffer=FileBufferToImageBuffer(pFileBuffer,ppImageBuffer); if(!SizeOfBuffer) { printf("调用FileBufferToImageBuffer函数失败"); return 0; } //调用AddSection函数 pImageBuffer=AddSection(pImageBuffer); //调用ImageBufferToBuffer SizeOfBuffer=ImageBufferToFileBuffer(pImageBuffer,ppBuffer); pBuffer=*ppBuffer; if(!SizeOfBuffer) { printf("SizeOfBuffer error"); return 0; } //调用MemeryToFile if(MemeryToFile(pBuffer,SizeOfBuffer)==false) { printf("end"); return 0; } return 0; }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)