在内存中读取函数的ShellCode并执行

在内存中读取函数的ShellCode并执行

下面是一个例子,实现的效果是将fun1函数的十六进制读取出来,在内存中将str1的地址改成str2,分配一块内存,将改好的函数的ShellCode写入并执行。

// FunTest.cpp : 定义控制台应用程序的入口点。
//
//
#include "stdafx.h"
#include <windows.h>

#pragma comment(lib,"user32.lib")

char *str1 = "aaaa";  //字符串指针1
char *str2 = "bbbb";  //字符串指针2

void fun1()
{
	MessageBox(0,str1,0,0);
}

void fun2()
{
	MessageBox(0,"2",0,0);
}


int _tmain(int argc, _TCHAR* argv[])
{

	fun1();  //调用fun1函数测试一下

	//获取fun1函数的大小
	int iFun1Size = ((DWORD)fun2) - ((DWORD)fun1);
	printf("fun1 size: %d\n",iFun1Size);

	//获取fun1函数的十六进制内容
	BYTE *pFun1Body = new BYTE [iFun1Size];
	memcpy(pFun1Body,&fun1,iFun1Size);
	for (int i=0;i<=iFun1Size;i++)
	{
		printf("%x",*(pFun1Body+i));
	}
	printf("\n");
	

	//打印字符指针地址
	DWORD dwstrAddress1 = (DWORD)&str1;
	DWORD dwstrAddress2 = (DWORD)&str2;
	printf("Address1 %x\n",dwstrAddress1);
	printf("Address2 %x\n",dwstrAddress2);

	//判断
	for (int i=0;i<(iFun1Size-4);i++)
	{
		DWORD *dwPtr = (DWORD *)((BYTE *)pFun1Body + i);
		
		//找str1的地址
		if (*dwPtr == dwstrAddress1) 
		{
			*dwPtr = (DWORD)dwstrAddress2;  //替换字符串指针地址
			printf("dwstrAddress1 found\n");
		}
		else if (*dwPtr == dwstrAddress2)
		{
			printf("dwstrAddress2 found\n");
		}

	}
	
	//分配内存
	PVOID pData = VirtualAlloc(NULL,iFun1Size,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
	if(!pData)
	{
		DWORD dwError = GetLastError();
		printf("VirtualAllocEx error %d \n",dwError);
		return 0;
	}


	//写内存
	HANDLE h = OpenProcess(PROCESS_ALL_ACCESS,0,GetCurrentProcessId());
	if(!WriteProcessMemory(h,pData,pFun1Body,iFun1Size,0))
	{
		DWORD dwError = GetLastError();
		printf("WriteProcessMemory error %d\n",dwError);
		return 0;
	}
	
	//执行
	_asm
	{
		mov eax,pData;
		call eax
	}

	//释放内存
	VirtualFree(pData,0,MEM_RELEASE);
	delete []pFun1Body;

	getchar();
	return 0;
}


 

你可能感兴趣的:(在内存中读取函数的ShellCode并执行)