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