增加节表存放shellcode

将shellcode放在PE文件新增的节表中

// InsertShellCodeToPE.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <Windows.h>

#define FILENAME	"hello.exe"

//自定义的shellcode
char shellcode[] = "\x90\x90\x90\x90\xb8\x90\x90\x90\x90\xff\xe0\x00";

/************************************************************************/
/* 函数说明:将dwNum按dwAlign大小生成对齐大小                           */
/* 参数:dwNum 待对齐的数据长度				                            */
/*		 dwAlign  对齐粒度										        */
/* 返回值:返回按指定粒度对齐后的大小		                            */
/************************************************************************/
DWORD Align(DWORD dwNum, DWORD dwAlign)
{
	if (dwNum % dwAlign == 0)
	{
		return dwNum;
	}
	else
	{
		return (dwNum / dwAlign + 1) * dwAlign;
	}
}


int main(int argc, char* argv[])
{
	HANDLE hFile = ::CreateFile(FILENAME, FILE_GENERIC_READ|FILE_GENERIC_WRITE|FILE_GENERIC_EXECUTE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (NULL == hFile)
	{
		printf("createfile error");
		return -1;
	}
	HANDLE hFileMap = ::CreateFileMapping(hFile, NULL, PAGE_EXECUTE_READWRITE, 0, 0, NULL);
	int n = GetLastError();
	if (NULL == hFileMap)
	{
		printf("CreateFileMapping error");
		return -1;
	}
	LPVOID lpMemory = ::MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
	if (NULL == lpMemory)
	{
		printf("MapViewOfFile error");
		return -1;
	}
	
	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpMemory;
	PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)lpMemory + pDosHeader->e_lfanew);
	PIMAGE_FILE_HEADER pFileHeader = (PIMAGE_FILE_HEADER)&(pNTHeader->FileHeader);
	PIMAGE_OPTIONAL_HEADER pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)&pNTHeader->OptionalHeader;

	PIMAGE_SECTION_HEADER pSection = NULL;
	IMAGE_SECTION_HEADER secToAdd = {0};

	if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE || pNTHeader->Signature != IMAGE_NT_SIGNATURE)
	{
		printf("Not valid PE file...");
		return -1;
	}

	pSection = (PIMAGE_SECTION_HEADER)((BYTE*)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
	
	DWORD dwSectionNum = pFileHeader->NumberOfSections;
	DWORD dwSectionAlign = pOptionalHeader->SectionAlignment;
	DWORD dwOEP = pOptionalHeader->AddressOfEntryPoint;
	dwOEP = (DWORD)(pOptionalHeader->ImageBase + dwOEP);

	
	pSection = pSection + dwSectionNum - 1;		//pSection指向了最后一个section节表的起始,下面根据最后一个section节表设置新的节表数据
	strcpy((char *)secToAdd.Name, ".xiaoju");
	secToAdd.Characteristics = pSection->Characteristics;
	secToAdd.VirtualAddress = pSection->VirtualAddress + Align(pSection->Misc.VirtualSize, dwSectionAlign);
	secToAdd.Misc.VirtualSize = dwSectionAlign;
	secToAdd.PointerToRawData = pSection->PointerToRawData + pSection->SizeOfRawData;
	secToAdd.SizeOfRawData = dwSectionAlign;

	pSection++; //pSection指向了所有节表的最后
	//写入新的节表
	memcpy(pSection, &secToAdd, sizeof(IMAGE_SECTION_HEADER));

	//改写pe文件中节表的数量
	pFileHeader->NumberOfSections++;

	//将shellcode中的预留位填充好
	*(DWORD*)&shellcode[5] = dwOEP;

	//增加文件大小
	BYTE bNum = '\x0';
	DWORD dwWritten = 0;
	::SetFilePointer(hFile, 0, 0, FILE_END);
	::WriteFile(hFile, &bNum, dwSectionAlign, &dwWritten, NULL);

	//在新增节表的PointerToRawData处写入shellcode
	::SetFilePointer(hFile, pSection->PointerToRawData, 0, FILE_BEGIN);
	::WriteFile(hFile, shellcode, strlen(shellcode)+3, &dwWritten, NULL);

	//修改程序的映象大小和OEP
	pOptionalHeader->SizeOfImage = pOptionalHeader->SizeOfImage + dwSectionAlign;
	pOptionalHeader->AddressOfEntryPoint = pSection->VirtualAddress;

	::UnmapViewOfFile(lpMemory);

	
	::CloseHandle(hFileMap);
	::CloseHandle(hFile);

	return 0;
}

原始hello.exe

增加节表存放shellcode_第1张图片



程序运行后,修改后的hello.exe

增加节表存放shellcode_第2张图片




你可能感兴趣的:(增加节表存放shellcode)