將shellcode 插入到PE節表的間隔中

將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";


DWORD FindSpace(LPVOID lpBase, PIMAGE_NT_HEADERS pNTHeader)
/************************************************************************/
/* 函數說明:在PE的每一個區塊中查找空閒位置                             */
/* 參數:lpBase PE文件在內存中的基地址		                            */
/*		 pNTHeader  PE文件的NT頭的指針							        */
/* 返回值:成功返回找到的空閒地址,否則返回0                            */
/************************************************************************/
{
	PIMAGE_SECTION_HEADER pSection;
	pSection = (PIMAGE_SECTION_HEADER)((BYTE*)&pNTHeader->OptionalHeader + pNTHeader->FileHeader.SizeOfOptionalHeader);
	DWORD dwAddr;
	dwAddr = pSection->PointerToRawData + pSection->SizeOfRawData - sizeof(shellcode);
	dwAddr = (DWORD)((BYTE*)lpBase + dwAddr);

	while (dwAddr > pSection->Misc.VirtualSize)
	{
		DWORD i = 0;
		for (i =0; i < strlen(shellcode); i++)
		{
			if (*((BYTE*)dwAddr + i )!= 0 )
			{
				break;
			}
		}
		if (i == strlen(shellcode))
		{
			return dwAddr;
		}
		dwAddr--;
	}
	return 0;
}


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 (INVALID_HANDLE_VALUE == hFile)
	{
		printf("createfile error");
		return -1;
	}
	HANDLE hFileMap = ::CreateFileMapping(hFile, NULL,  PAGE_READWRITE, 0, 0, NULL);
	int n = GetLastError();
	if (NULL == hFileMap)
	{
		printf("CreateFileMapping error");
		CloseHandle(hFile);
		return -1;
	}
	LPVOID lpMemory = ::MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
	if (NULL == lpMemory)
	{
		printf("MapViewOfFile error");
		CloseHandle(hFileMap);
		CloseHandle(hFile);
		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...");
		UnmapViewOfFile(lpMemory);
		CloseHandle(hFileMap);
		CloseHandle(hFile);
		return -1;
	}

	DWORD dwAddr = FindSpace(lpMemory, pNTHeader);
	if (dwAddr == 0)
	{
		printf("the first section DO NOT has enough space");
		UnmapViewOfFile(lpMemory);
		CloseHandle(hFileMap);
		CloseHandle(hFile);
		return -1;
	}

	DWORD dwOEP = pOptionalHeader->AddressOfEntryPoint;
	dwOEP = (DWORD)(pOptionalHeader->ImageBase + dwOEP);


	//先得到shellcode的長度,因爲下面填充後會有\x00被填充進去
	DWORD dwShellcodeLen = strlen(shellcode);
	//將shellcode中的預留位填充好
	*(DWORD*)&shellcode[5] = dwOEP;

	memcpy((char*)dwAddr, shellcode, dwShellcodeLen);

	dwAddr = dwAddr - (DWORD)(BYTE*)lpMemory;
	pNTHeader->OptionalHeader.AddressOfEntryPoint = dwAddr;

	

	::UnmapViewOfFile(lpMemory);

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

	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章