so I have my C++/CLI application which injects itself into a target process. But while the injection seems succesfull the entry point doesnt get called. This is my injector:
#include "stdafx.h"
#include <Windows.h>
#include <TlHelp32.h>
#include <string>
#include <stdlib.h>
#include <comdef.h>
#include "Hooking.h"
#include "HCommonEnsureCleanup.h"
VOID Hooking::HookProcess()
{
DWORD firefox = Hooking::FindProcessId("firefox.exe");
Inject(firefox);
}
BOOL Hooking::Inject(DWORD pID)
{
const wchar_t* DLL_NAME = (const wchar_t*)(void*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(System::Windows::Forms::Application::ExecutablePath);
HANDLE Proc;
HMODULE hLib;
char buf[50] = { 0 };
LPVOID RemoteString, LoadLibAddy;
if (!pID)
return false;
Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
if (!Proc)
{
return false;
}
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
RemoteString = (LPVOID)VirtualAllocEx(Proc, NULL, (wcslen(DLL_NAME) + 1) * sizeof(wchar_t), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(Proc, (LPVOID)RemoteString, DLL_NAME, (wcslen(DLL_NAME) + 1) * sizeof(wchar_t), NULL);
CreateRemoteThread(Proc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, NULL, NULL);
CloseHandle(Proc);
return true;
}
DWORD Hooking::FindProcessId(const char *processname)
{
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
DWORD result = NULL;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (INVALID_HANDLE_VALUE == hProcessSnap) return(FALSE);
pe32.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hProcessSnap, &pe32))
{
CloseHandle(hProcessSnap);
return(NULL);
}
do
{
if (0 == strcmp(processname, _bstr_t(pe32.szExeFile)))
{
result = pe32.th32ProcessID;
break;
}
} while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return result;
}
and then(since my program is an executeable) I made a dll entry point:
int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
Hooking::HookProcess();
return 0;
}
BOOL WINAPI DllMain(
HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved
)
{
MessageBoxA(NULL, "Injection OK", "Injection OK", NULL);
}
However, neither of my entry points, either Dll or exe gets called. So I was thinking that this may be because this exe contains .Net code but before changing it all I wanted to ask it here.
Thank you for your time
Firstly, change "(wcslen(DLL_NAME) + 1) * sizeof(wchar_t)" to "wcslen(DLL_NAME)", that will be sufficient. Make sure to update the memory allocation as well.
Secondly, you're passing a unicode-encoded buffer to LoadLibraryA. That isn't going to work because LoadLibraryA doesn't accept unicode-encoded buffers, it expects an Ascii-encoded buffer. Use LoadLibraryW instead.
Thirdly, you aren't doing any error checking. You cannot just assume that the two virtual memory operations and the remote thread creation operation will be successful, you need to check the return status of each operation to ensure it was successful, otherwise stop pursuing the injection routine. This will also shine insight as to why the operation is failing. You need to attach a debugger to the targeted process to ensure that the memory is as it should be after allocating and writing to it, too.
Last but not least, make sure you have the sufficient privileges to target the targeted process. For example, you cannot target a process which is elevated if you're running with standard rights, and you cannot target a traditional security solution which has self-protection enabled. There's many different factors here.