⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 perealign.cpp

📁 一些初级的网络编程
💻 CPP
字号:
#include <windows.h>
#include "perealign.h"
#include "peutils.h"

#define MAX_SEC_NUM         30

const   DWORD ScanStartDS = 0x40;
const   MinSectionTerm    = 5;

DWORD RealignPE(LPVOID lpMapping, DWORD dwFileSize)
{
	DWORD                dwMapBase;
	LPVOID               pMap;
	DWORD				 dwTmpNum,dwSectionBase;
	WORD                 wTmpNum;
	CHAR *	             pCH;
	WORD *			     pW;
	LPVOID               pSections[MAX_SEC_NUM];

	PIMAGE_DOS_HEADER       pDosh;
	PIMAGE_NT_HEADERS		pPeh;
	PIMAGE_SECTION_HEADER   pSectionh;
	int                     i,ii;

	ZeroMemory(&pSections, sizeof(pSections));
	
	// get the other parameters
	pMap = lpMapping;
	dwMapBase = (DWORD)pMap;
	
	if (dwFileSize == 0 || pMap == NULL)
	{
		return 1;
	}
	
	// access the PE Header and check whether it's a valid one
	pDosh = (PIMAGE_DOS_HEADER)(pMap);
	if (pDosh->e_magic != IMAGE_DOS_SIGNATURE)
	{
		return 2;
	}
	pPeh = (PIMAGE_NT_HEADERS)((DWORD)pDosh+pDosh->e_lfanew);
	if (pPeh->Signature != IMAGE_NT_SIGNATURE)
	{
		return 2;
	}
	if (pPeh->FileHeader.NumberOfSections > MAX_SEC_NUM)
	{
		return 3;
	}
	
	__try
	{
		/* START */
		pPeh->OptionalHeader.FileAlignment = 0x200;
		
		/* Realign the PE Header */
		// get the size of all headers
		dwTmpNum = 0xf8 + pPeh->FileHeader.NumberOfSections * 0x28;

		// kill room between the "win32 pls" message and the PE signature
		// find the end of the message
		pW = (WORD*)(dwMapBase + ScanStartDS);
		while (*pW != 0 || (!IsRoundedTo((DWORD)pW,0x10)))
		{
			pW = (WORD*)((DWORD)pW+1);
		}
		wTmpNum = (WORD)((DWORD)pW-dwMapBase);
		if (wTmpNum < pDosh->e_lfanew)
		{
			CopyMemory((LPVOID)pW,(VOID*)pPeh,dwTmpNum); // copy the Header to the right place

			dwSectionBase = ValidAlignment(dwTmpNum + pDosh->e_lfanew, 0x200);
			// blank out end of aligned optional header
			DWORD dwT1 = (DWORD)pW + dwTmpNum;
			DWORD dwT2 = dwSectionBase-(dwT1 - dwMapBase);
			memset((LPVOID)dwT1, 0, dwT2);

			pDosh->e_lfanew = wTmpNum;
		}
				
		dwSectionBase = ValidAlignment(dwTmpNum + pDosh->e_lfanew, 0x200);
		pPeh = (PIMAGE_NT_HEADERS)(dwMapBase+pDosh->e_lfanew); // because the NT header moved
		// correct the SizeOfHeaders
		pPeh->OptionalHeader.SizeOfHeaders = dwSectionBase;
		
		/* Realign all sections */
		// make a copy of all sections
		// this is needed if the sections aren't sorted by their RawOffset (e.g. Petite)
		pSectionh = (PIMAGE_SECTION_HEADER)(dwMapBase+pDosh->e_lfanew+0xf8);
		for (i=0; i<pPeh->FileHeader.NumberOfSections; i++)
		{
			if (pSectionh->SizeOfRawData == 0 || pSectionh->PointerToRawData == 0)
			{
				++pSectionh;
				continue;
			}
			// get a valid size
			dwTmpNum = pSectionh->SizeOfRawData;
			if ((pSectionh->SizeOfRawData+pSectionh->PointerToRawData) > dwFileSize)
				dwTmpNum = dwFileSize-pSectionh->PointerToRawData;
			dwTmpNum -= 1;
			// copy the section into some memory
			pSections[i] = GlobalAlloc(0,dwTmpNum);
			if (pSections[i] == NULL) // fatal error !!!
			{
				for (ii=0; ii<i-1; ii++)
					if (pSections[ii])
						GlobalFree(pSections[ii]);
					return 4;
			}
			CopyMemory(pSections[i],(LPVOID)(pSectionh->PointerToRawData+dwMapBase),dwTmpNum);
			++pSectionh;
		}
		
		// start realigning the sections
		pSectionh = (PIMAGE_SECTION_HEADER)(dwMapBase+pDosh->e_lfanew+0xf8);
		for (i=0;i<pPeh->FileHeader.NumberOfSections;i++)
		{
			// some anti crash code :P
			if (pSectionh->SizeOfRawData == 0 || pSectionh->PointerToRawData == 0)
			{
				++pSectionh;
				if (pSectionh->PointerToRawData == 0)
					continue;
				pSectionh->PointerToRawData = dwSectionBase;
				continue;
			}
			// let pCH point to the end of the current section
			if ((pSectionh->PointerToRawData+pSectionh->SizeOfRawData) <= dwFileSize)
				pCH = (char*)(dwMapBase+pSectionh->PointerToRawData+pSectionh->SizeOfRawData-1);
			else
				pCH = (char*)(dwMapBase+dwFileSize-1);
			// look for the end of this section
			while (*pCH == 0)
				--pCH;
			// calculate the new RawSize
			dwTmpNum = ((DWORD)pCH-dwMapBase)+MinSectionTerm-pSectionh->PointerToRawData;

			// copy the section to the new place
			//if (i != pPeh->FileHeader.NumberOfSections-1)
				dwTmpNum = 	ValidAlignment(dwTmpNum, 0x200);
			
			if (dwTmpNum < pSectionh->SizeOfRawData)
				pSectionh->SizeOfRawData = dwTmpNum;
			else // the new size is too BIG
				dwTmpNum = pSectionh->SizeOfRawData;

			CopyMemory((LPVOID)(dwMapBase+dwSectionBase),pSections[i],
				dwTmpNum);
			// set the RawOffset
			pSectionh->PointerToRawData = dwSectionBase;
			// get the RawOffset for the next section
			dwSectionBase = dwTmpNum+dwSectionBase; // the last section doesn't need to be aligned
			// go to the next section
			++pSectionh;
		}
		
		// delete bound import directories because it is destroyed if present
		pPeh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
		pPeh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;
		
		// clean up
		for (i=0;i<pPeh->FileHeader.NumberOfSections;i++)
			if (pSections[i])
				GlobalFree(pSections[i]);
	}
	__except(1)
	{
		// clean up
		for (i=0; i<pPeh->FileHeader.NumberOfSections; i++)
			if (pSections)
				GlobalFree(pSections[i]);
			return 0;
	}
	return dwSectionBase; // return the new filesize
}

BOOL IsRoundedTo(DWORD dwTarNum,DWORD dwRoundNum)
{
	div_t  d;

	d = div(dwTarNum,dwRoundNum);
	return (d.rem == 0);
}

DWORD ValidAlignment(DWORD dwSize, DWORD dwAlignment)
{
	div_t DivRes;

	DivRes = div(dwSize, dwAlignment);
	if (DivRes.rem == 0)
		return dwSize;
	return ((DivRes.quot+1) * dwAlignment);
}

DWORD StripReloc(LPVOID lpMapping)
{
	PIMAGE_DOS_HEADER pDosHdr = 0;
	PIMAGE_NT_HEADERS pNtHdr = 0;
	PIMAGE_SECTION_HEADER pSecHdr = 0;
	DWORD dwSecStart = 0;
	DWORD dwKatSup = 0;
	DWORD dwBytesWritten = 0;
	LONG lJmp = 0;
	WORD wNumSections = 0;
	WORD wSizeO = 0;
	int i = 0;
	char* szSectionName = 0;
	DWORD dwTempSize = 0;

	pDosHdr = (PIMAGE_DOS_HEADER) lpMapping;
	lJmp = pDosHdr->e_lfanew;
	dwKatSup = (DWORD)pDosHdr;
	dwKatSup += lJmp;

	pNtHdr = (PIMAGE_NT_HEADERS)dwKatSup;

	wNumSections = pNtHdr->FileHeader.NumberOfSections;
	wSizeO = pNtHdr->FileHeader.SizeOfOptionalHeader;

	dwSecStart = (DWORD)pNtHdr;
	dwSecStart += 24;
	dwSecStart += wSizeO;

	// Get reloc section name
	if(pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0)
	{
		szSectionName = RVAToSectionName(pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress, lpMapping);

		if(szSectionName)
		{
			for(i = 0; i < wNumSections; i++)
			{
				pSecHdr = (PIMAGE_SECTION_HEADER)dwSecStart;

				if((strcmp((char*)pSecHdr->Name, szSectionName) == 0) && (i == wNumSections-1))
				{
					pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = 0;
					pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = 0;

					pNtHdr->FileHeader.NumberOfSections--;
					pNtHdr->OptionalHeader.SizeOfImage = pSecHdr->VirtualAddress + ValidAlignment(pSecHdr->Misc.VirtualSize, pNtHdr->OptionalHeader.SectionAlignment);

					return dwTempSize;
				}

				dwTempSize += pSecHdr->SizeOfRawData;

				// move to next section header
				dwSecStart += sizeof(IMAGE_SECTION_HEADER);
			}
		}
	}

	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -