Code:#include <Windows.h> #include <TlHelp32.h> typedef HMODULE(WINAPI *pLoadLibraryA)(LPCSTR); typedef FARPROC(WINAPI *pGetProcAddress)(HMODULE, LPCSTR); typedef BOOL(WINAPI *PDLL_MAIN)(HMODULE, DWORD, PVOID); typedef struct _MANUAL_INJECT { PVOID ImageBase; PIMAGE_NT_HEADERS NtHeaders; PIMAGE_BASE_RELOCATION BaseRelocation; PIMAGE_IMPORT_DESCRIPTOR ImportDirectory; pLoadLibraryA fnLoadLibraryA; pGetProcAddress fnGetProcAddress; }MANUAL_INJECT, *PMANUAL_INJECT; unsigned long __stdcall LoadDll(PVOID p) { PMANUAL_INJECT ManualInject; HMODULE hModule; DWORD i, Function, count, delta; DWORD* ptr; WORD* list; PIMAGE_BASE_RELOCATION pIBR; PIMAGE_IMPORT_DESCRIPTOR pIID; PIMAGE_IMPORT_BY_NAME pIBN; PIMAGE_THUNK_DATA FirstThunk, OrigFirstThunk; PDLL_MAIN EntryPoint; ManualInject = (PMANUAL_INJECT)p; pIBR = ManualInject->BaseRelocation; delta = (DWORD)((LPBYTE)ManualInject->ImageBase - ManualInject->NtHeaders->OptionalHeader.ImageBase); // Calculate the delta // Relocate the image while (pIBR->VirtualAddress) { if (pIBR->SizeOfBlock >= sizeof(IMAGE_BASE_RELOCATION)) { count = (pIBR->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD); list = (PWORD)(pIBR + 1); for (i = 0; i<count; i++) { if (list[i]) { ptr = (PDWORD)((LPBYTE)ManualInject->ImageBase + (pIBR->VirtualAddress + (list[i] & 0xFFF))); *ptr += delta; } } } pIBR = (PIMAGE_BASE_RELOCATION)((LPBYTE)pIBR + pIBR->SizeOfBlock); } pIID = ManualInject->ImportDirectory; // Resolve DLL imports while (pIID->Characteristics) { OrigFirstThunk = (PIMAGE_THUNK_DATA)((LPBYTE)ManualInject->ImageBase + pIID->OriginalFirstThunk); FirstThunk = (PIMAGE_THUNK_DATA)((LPBYTE)ManualInject->ImageBase + pIID->FirstThunk); hModule = ManualInject->fnLoadLibraryA((LPCSTR)ManualInject->ImageBase + pIID->Name); if (!hModule) { return FALSE; } while (OrigFirstThunk->u1.AddressOfData) { if (OrigFirstThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) { // Import by ordinal Function = (DWORD)ManualInject->fnGetProcAddress(hModule, (LPCSTR)(OrigFirstThunk->u1.Ordinal & 0xFFFF)); if (!Function) { return FALSE; } FirstThunk->u1.Function = Function; } else { // Import by name pIBN = (PIMAGE_IMPORT_BY_NAME)((LPBYTE)ManualInject->ImageBase + OrigFirstThunk->u1.AddressOfData); Function = (DWORD)ManualInject->fnGetProcAddress(hModule, (LPCSTR)pIBN->Name); if (!Function) { return FALSE; } FirstThunk->u1.Function = Function; } OrigFirstThunk++; FirstThunk++; } pIID++; } if (ManualInject->NtHeaders->OptionalHeader.AddressOfEntryPoint) { EntryPoint = (PDLL_MAIN)((LPBYTE)ManualInject->ImageBase + ManualInject->NtHeaders->OptionalHeader.AddressOfEntryPoint); return EntryPoint((HMODULE)ManualInject->ImageBase, DLL_PROCESS_ATTACH, NULL); // Call the entry point } return TRUE; } unsigned long __stdcall LoadDllEnd() { return 0; } void ManualMap(const char* dll, unsigned long pid) { PIMAGE_DOS_HEADER pIDH; PIMAGE_NT_HEADERS pINH; PIMAGE_SECTION_HEADER pISH; HANDLE hProcess, hThread, hFile, hToken; PVOID buffer, image, mem; DWORD i, FileSize, ProcessId, ExitCode, read; TOKEN_PRIVILEGES tp; MANUAL_INJECT ManualInject; if (OpenProcessToken((HANDLE)-1, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; tp.Privileges[0].Luid.LowPart = 20; tp.Privileges[0].Luid.HighPart = 0; AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL); CloseHandle(hToken); } hFile = CreateFile(dpath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); // Open the DLL FileSize = GetFileSize(hFile, NULL); buffer = VirtualAlloc(NULL, FileSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); ReadFile(hFile, buffer, FileSize, &read, NULL); CloseHandle(hFile); pIDH = (PIMAGE_DOS_HEADER)buffer; pINH = (PIMAGE_NT_HEADERS)((LPBYTE)buffer + pIDH->e_lfanew); ProcessId = pid; hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId); image = VirtualAllocEx(hProcess, NULL, pINH->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); // Allocate memory for the DLL pISH = (PIMAGE_SECTION_HEADER)(pINH + 1); for (i = 0; i<pINH->FileHeader.NumberOfSections; i++) { WriteProcessMemory(hProcess, (PVOID)((LPBYTE)image + pISH[i].VirtualAddress), (PVOID)((LPBYTE)buffer + pISH[i].PointerToRawData), pISH[i].SizeOfRawData, NULL); } mem = VirtualAllocEx(hProcess, NULL, 4096, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); // Allocate memory for the loader code memset(&ManualInject, 0, sizeof(MANUAL_INJECT)); ManualInject.ImageBase = image; ManualInject.NtHeaders = (PIMAGE_NT_HEADERS)((LPBYTE)image + pIDH->e_lfanew); ManualInject.BaseRelocation = (PIMAGE_BASE_RELOCATION)((LPBYTE)image + pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); ManualInject.ImportDirectory = (PIMAGE_IMPORT_DESCRIPTOR)((LPBYTE)image + pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); ManualInject.fnLoadLibraryA = LoadLibraryA; ManualInject.fnGetProcAddress = GetProcAddress; WriteProcessMemory(hProcess, mem, &ManualInject, sizeof(MANUAL_INJECT), NULL); // Write the loader information to target process WriteProcessMemory(hProcess, (PVOID)((PMANUAL_INJECT)mem + 1), LoadDll, (DWORD)LoadDllEnd - (DWORD)LoadDll, NULL); // Write the loader code to target process hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)((PMANUAL_INJECT)mem + 1), mem, 0, NULL); // Create a remote thread to execute the loader code if (!hThread) { MessageBox(0, L"Error: Unable to execute loader code (%d)\n", L"ERROR_EXECUTE_FAIL", MB_ICONEXCLAMATION); VirtualFreeEx(hProcess, mem, 0, MEM_RELEASE); VirtualFreeEx(hProcess, image, 0, MEM_RELEASE); CloseHandle(hProcess); VirtualFree(buffer, 0, MEM_RELEASE); return -1; } WaitForSingleObject(hThread, INFINITE); GetExitCodeThread(hThread, &ExitCode); if (!ExitCode) { VirtualFreeEx(hProcess, mem, 0, MEM_RELEASE); VirtualFreeEx(hProcess, image, 0, MEM_RELEASE); CloseHandle(hThread); CloseHandle(hProcess); VirtualFree(buffer, 0, MEM_RELEASE); return -1; } CloseHandle(hThread); VirtualFreeEx(hProcess, mem, 0, MEM_RELEASE); CloseHandle(hProcess); VirtualFree(buffer, 0, MEM_RELEASE); ZeroMemory(&pid, sizeof(pid)); ZeroMemory(&dpath, sizeof(dpath)); return 0; }