This is not really a solution as you would expect, but more a description of what are the limits of the injection process and why what you want to do is not 'easy' to achive.
I sayd easy not impossible, because some very sofisticated techniques can be used to overcome the missing relocation of memory addresses in the host process. But this lead more to dark hacking for virus creation than legitimate research (even if the injection should be limited to processes with same rights so de facto giving no advantages).
The problem is that the memory addresses you have in the injected code are not valid in the hacked process, so you cannot call any library function, nor load any data.
If you read more carefully the article from where you based your code you'll see that at the base of all the theory is clearly stated the assumption that the only functions you'll call from your code are LoadLibrary and FreeLibrary that are in kernel32 library and
are expected to be loaded at same address in both processes and linked to process memory space (relocation).
So if you try the following simplified code:
#include <windows.h>
#include <stdio.h>
typedef DWORD_PTR __stdcall (*TInjFun)(LPVOID);
void *inject(HANDLE hProcess, LPVOID data, size_t dataSize)
{
LPVOID remoteMemoryAddress = 0;
SIZE_T bytesTesferred = 0; remoteMemoryAddress = VirtualAllocEx(hProcess,
0,
dataSize,
MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if (remoteMemoryAddress == 0) {
return 0;
}
BOOL succeed = WriteProcessMemory(hProcess,
(LPVOID)remoteMemoryAddress,
(LPCVOID)data,
dataSize,
&bytesTesferred);
if (!succeed){
return NULL;
}
return remoteMemoryAddress;
}
DWORD_PTR __stdcall InjFun(LPVOID p)
{
return (DWORD_PTR)p+1;
}
void EndInj(void){};
int main(int argc, char *argv[])
{
TInjFun InjectedFun = inject(GetCurrentProcess(), InjFun, (DWORD_PTR)EndInj-(DWORD_PTR)InjFun);
for (int i=0; i<10; i++)
{
int r = InjectedFun((LPVOID)i);
if (r != i+1)
{
printf ("Error. Expected %d got %d.\n", i+1, r);
break;
}
printf ("Expected %d got %d - OK.\n", i+1, r);
}
for (int i=0; i<10; i++)
{
DWORD dwThreadId = 0;
HANDLE hThread = CreateRemoteThreadEx(GetCurrentProcess(), NULL, 0,
(LPTHREAD_START_ROUTINE)InjectedFun,
(LPVOID)i, 0, NULL, &dwThreadId);
if (hThread == NULL)
{
printf("Error Creating remote thread!\n");
return -1;
}
WaitForSingleObject(hThread, INFINITE);
DWORD_PTR r = 0;
GetExitCodeThread(hThread, &r);
CloseHandle(hThread);
if (r != i+1)
{
printf ("Error. Expected %d got %d.\n", i+1, r);
break;
}
printf ("Expected %d got %d - OK.\n", i+1, r);
}
}
it will work because the injected routine make no use of any function or data, that in the remote process will have different addresses (even attaching to the same process).
Just enable the printf inside the injected code and you'll get memory access exception.
I hope to have been clear enaugh.