滴水---------新增节

滴水---------新增节,第1张

滴水---------新增节

上节课讲到任意节添加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(FreebaseNumberOfSections=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;iNumberOfSections-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(FreebaseNumberOfSections=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;iNumberOfSections-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;iNumberOfSections;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;



}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5703069.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存