x86 way of doing this is easy and straightforward - through GetExitCodeThread. Unfortunately it's limited to returning 32 bit values. As I understand it WinAPI provides no 64 bit alternative.
So the problem is - I have no trouble calling the injected function by finding its base address through CreateToolhelp32Snapshot module loop then running CreateRemoteThread using it, it does whatever I wrote in it as it should but how exactly do I retrieve its return value without GetExitCodeThread? As an example I want to retrieve a 64bit pointer or even a struct (or a 64bit pointer to one) as a result of this function. What would be a correct way of doing it? And if it's ReadProcessMemory - then which memory address/offset should I read for a return value?
Edit: additional info: I'm calling a function inside an injected DLL. The function executes some stuff (e.g. collection of data from the process it's injected into, which is successful) - the problem is I want to retrieve one of those variables back into the calling process (the one that calls CreateRemoteThread). GetExitCodeThread is a no go because variables are 64 bit.
code snippet for reference (hExportThread function returns uint64_t in DLL):
// LLAddr = LoadLibraryA address, lpBaseAddr = dll path related argument
HANDLE hInjectionThread = CreateRemoteThread(hProc, NULL, NULL, LLAddr, lpBaseAddr, NULL, &idThread);
WaitForSingleObject(hInjectionThread, INFINITE);
dllBaseAddr = getDLLBaseAddr(); // gets base address of the injected DLL
dllExportOffset = getDLLExportOffset(dllExportName.c_str()); // opens the DLL in the local buffer and gets the correct offset
LPTHREAD_START_ROUTINE lpNewThread = LPTHREAD_START_ROUTINE(dllBaseAddr + dllExportOffset); // gets the correct address of the function in the injected dll
HANDLE hExportThread = CreateRemoteThread(hProc, NULL, NULL, lpNewThread, NULL, NULL, 0); // executes injected function
WaitForSingleObject(hExportThread, INFINITE);