在内存中读取函数的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;
}