// InjectDll.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "ZInjectDll.h"
#ifdef UNICODE
#define LoadLibraryName TEXT("LoadLibraryW")
#else
#define LoadLibraryName TEXT("LoadLibraryA")
#endif
const int MAXINJECTSIZE = 4096;
typedef HMODULE (__stdcall * LPLOADLIBRARY)(LPCTSTR);
typedef FARPROC (__stdcall * LPGETPROCADDRESS)(HMODULE, LPCTSTR);
typedef BOOL (__stdcall * LPFREELIBRARY)(HMODULE);
typedef LRESULT (__stdcall * LPINSTALL)(HWND);
typedef struct
{
LPLOADLIBRARY prcLoadLib;
LPGETPROCADDRESS prcGetProcAddr;
LPFREELIBRARY prcFreeLib;
TCHAR szLibPath[MAX_PATH];
HWND hInjectWnd;
}INJECT_DLL, *LPINJECT_DLL;
void EnableDebugPriv()
{
HANDLE hToken;
LUID sedebugnameValue;
TOKEN_PRIVILEGES tkp;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
return;
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue))
{
CloseHandle(hToken);
return;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = sedebugnameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL))
CloseHandle(hToken);
}
DWORD __stdcall InjectedThread(LPVOID lpVoid)
{
try
{
LPINJECT_DLL lpInject = (LPINJECT_DLL)lpVoid;
if (NULL == lpInject)
return -1;
HMODULE hMod = lpInject->prcLoadLib(lpInject->szLibPath);
if (NULL == hMod)
return -2;
LPINSTALL lpInstall;
lpInstall = (LPINSTALL)lpInject->prcGetProcAddr(hMod, MAKEINTRESOURCE(1));
if (!lpInstall)
{
lpInject->prcFreeLib(hMod);
return -3;
}
lpInstall(lpInject->hInjectWnd);
lpInject->prcFreeLib(hMod);
}
catch(...)
{
return -1;
}
return 0;
}
BOOL InJectDllIntoProcess(HWND hwnd, LPCTSTR dllname, BOOL bWaitForRemoteThread)
{
DWORD dwProcessID;
GetWindowThreadProcessId(hwnd, &dwProcessID);
HMODULE hModule = ::LoadLibrary(TEXT("kernel32"));
if (!hModule)
return FALSE;
INJECT_DLL pstInjectDll;
pstInjectDll.prcLoadLib = (LPLOADLIBRARY)::GetProcAddress(hModule, LoadLibraryName);
pstInjectDll.prcFreeLib = (LPFREELIBRARY)::GetProcAddress(hModule, TEXT("FreeLibrary"));
pstInjectDll.prcGetProcAddr = (LPGETPROCADDRESS)::GetProcAddress(hModule, TEXT("GetProcAddress"));
::FreeLibrary(hModule);
pstInjectDll.hInjectWnd = hwnd;
lstrcpy(pstInjectDll.szLibPath, dllname);
EnableDebugPriv();
HANDLE hInjectTarget = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
if (!hInjectTarget)
return FALSE;
LPBYTE lpExcelAddr = (LPBYTE)::VirtualAllocEx(hInjectTarget, NULL, MAXINJECTSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!lpExcelAddr)
return FALSE;
WriteProcessMemory(hInjectTarget, lpExcelAddr, &InjectedThread, MAXINJECTSIZE, 0);
LPINJECT_DLL param = (LPINJECT_DLL) VirtualAllocEx(hInjectTarget, 0, sizeof(INJECT_DLL), MEM_COMMIT, PAGE_READWRITE);
if (!param)
return FALSE;
WriteProcessMemory(hInjectTarget, param, &pstInjectDll, sizeof(INJECT_DLL), 0);
DWORD dwThreadId;
HANDLE hInjectThread = ::CreateRemoteThread(hInjectTarget, NULL, 0, (LPTHREAD_START_ROUTINE)lpExcelAddr, param, 0, &dwThreadId);
if (!hInjectThread)
return FALSE;
if (bWaitForRemoteThread)
{
WaitForSingleObject(hInjectThread, INFINITE);
VirtualFreeEx(hInjectTarget, lpExcelAddr, 0, MEM_RELEASE);
VirtualFreeEx(hInjectTarget, param, 0, MEM_RELEASE);
}
CloseHandle(hInjectThread);
CloseHandle(hInjectTarget);
return TRUE;
}