I got a simple question about the thread routine specified in CreateRemoteThread.

I once read somewhere that if the thread routine returns, the results will be unspecified.
So, does that mean that i should/have to call ExitThread instead of using a simple ret?

Maybe, if i just use a simple ret, some ressources might not be freed?

I've already seen some code which specifies the address of LoadLibraryA as the thread routine in CreateRemoteThread to load a dll into another process, but LoadLibraryA ends with a simple ret, so i doubt that this is a clean way of doing this?
Posted on 2004-07-25 10:21:12 by toxic
When you use a simple return the return value is in EAX, this is not guaranteed to be preserved between processes. If you use ExitThread you can specify the exit code and use GetExitCodeThread to obtain the proper value.
Posted on 2004-07-25 10:27:14 by donkey
Thanks for the reply!

So, is it generally valid to call GetThreadContext on the remote thread after it returns via a simple ret as long as i didn't close the thread handle via CloseHandle?
Posted on 2004-07-25 10:36:41 by toxic
Yes, as long as you don't close the handle the information is still valid.
Posted on 2004-07-25 10:40:28 by donkey
Thanks again!
Straight and direct answers, nice forum :)
Posted on 2004-07-25 10:42:40 by toxic
I just tried it. GetThreadContext returns 0, GetLastError returns 6 (invalid handle), although i haven't closed the thread handle yet. I use the same thread handle in WaitForSingleObject and no error occurs here.

Seems that i can't call GetThreadContext when the thread terminated.
Posted on 2004-07-25 11:09:00 by toxic
I am sorry, that is correct, I was thinking that you were trying on a suspended thread, I didn't read your post all the way through. My bad.
Posted on 2004-07-25 11:42:47 by donkey
Thanks for your help anyway. I will just write a dummy function which then calls the specified function and uses the return value as the parameter to ExitThread.

But i got another question:
What i need to do is call a function in another process and i need to check its return value.
Should i use CreateRemoteThread or should i redirect program flow via SetThreadContext on some thread in the target process?
Is it right that there might be problems when using SetThreadContext if the specified thread is blocked by a mutex or something?
Posted on 2004-07-25 12:37:05 by toxic
if i were you i would try this

jmp begin
pGetModuleHandle dd 0 ;or what ever you want
nReturnValue dd 0
call delta
pop ebp
sub ebp,offset delta ;Calculate problem
mov eax,[pGetModuleHandle+ebp]
push 0
call eax
mov [nReturnValue+ebp],eax
ret 4

InjCodeSize EQU InjectedCodeEnd-InjectedCodeBegin
szKrnl db "kernel32.dll"
szGMH db "GetModuleHandleA",0
hProcess dd 0
pInjCode dd 0
hThread dd 0
nThreadID dd 0
nTmp dd 0
nRemoteRetVal dd 0

invoke GetModuleHandle,addr szKrnl
mov edx,eax
invoke GetProcAddress,edx,addr szGMH
mov pGetModuleHandle,eax

invoke OpenProcess,PROCESS_ALL_ACCESS,0,ProcessID
mov hProcess,eax
invoke VirtualAllocEx,hProcess,0,InjCodeSize,MEM_COMMIT, PAGE_EXECUTE_READWRITE
mov pInjCode,eax
invoke WriteProcessMemory,hProcess,pInjCode,offset InjectedCodeBegin,InjCodeSize,addr nTmp
invoke CreateRemoteThread,hProcess,0,0,pInjCode,0,0,addr nThreadID
mov hThread,eax
invoke WaitForSingleObject,hThread,INFINITE
mov edx,pInjCode
add edx,5+4 ;5=jmp,4=pGetModuleHandle
invoke ReadProcessMemory,hProcess,edx,addr nRemoteRetVal,4,addr nTmp
;now nRemoteRetVal=nReturnValue
invoke VirtualFreeEx,hProcess,pInjCode,InjCodeSize, MEM_DECOMMIT
invoke CloseHandle,hProcess
Posted on 2004-07-25 17:30:38 by Criminal2
CreateRemoteThread is good if you're on NT (or use EliCZ' cross-platform wrapper), know the process won't terminate before you're done, and don't need to perform some action before the process does something.

If you need to create a loader, SetThreadContext will be fine, but you need to mess around a bit. Have a look at my XCOM bugfix loader, http://f0dder.has.it/ , it does load-time threadcontext patching.
Posted on 2004-07-25 19:32:50 by f0dder
Thanks for all the info so far!

But again, what i need is a general and safe method of executing some code in another process at any time (not specifically during load time). It should work both on win9x and win2k+.

So i need to use CreateRemoteThread (since its the safe way). But this only works on win2k+. So i need a method of emulating CreateRemoteThread on win9x. EliCZ's prchelp library does exactly what i need, but i'd like to write my own emulation functions.
Does anybody know where i can get some info about emulating CreateRemoteThread/VirtualAllocEx on win9x?

What i have to do to emulate VirtualAllocEx is just allocating memory in the shared memory area, right?
And the only thing i can think of emulating CreateRemoteThread is executing code in the target process which calls CreateThread. But to execute code in another process in win9x, i HAVE TO use debug functions like SetThreadContext, right? But i dont wanna use SetThreadContext when the program was already running for some period of time, because it might be blocked by an event/mutex/semaphore/whatever.
Posted on 2004-07-26 05:14:38 by toxic
there are undocummented ways to emulate OpenThread() on 9x. since you can only obtain dwThreadID and not hThread, search around on this board or try google. There is also a trick demonstrated by Matt Pietrek of emulating VirtualAllocEx under 9x, simply by allocating mem >2gig, which is shared memory. He does it by opening up a empty file mapping, which is not closed. Using SetThreadContext(), in conjunction to these two tricks, it's possible to then inject code into a running process, where you would call CreateThread(), to emulate CreateRemoteThread(). However, >NT4 does not have OpenThread(), nor toolhelp APIs to enumerate the processes/threads, so you must use NtOpenThread() and psapi APIs here, but who uses NT4 anyways? :)

i am almost certain this is exactly what EliCZ has done in EliRT

also under 9x, there is an undocummented API CreateKernelThread() which allows you to create a new thread in kernel, not really a CreateRemoteThread emulation, but a quick hack to get the work done :)
Posted on 2004-07-26 21:24:45 by Drocon
There is no trick to VirtualAllocEx on Win9x, they are simple ordinal exports:
Interprocess memory for 9x

invoke Alloc, cb ; Ordinal COMCTL32.DLL:71
Returns pv (pointer to virtual memory)

invoke ReAlloc, pv, cb ; Ordinal COMCTL32.DLL:72
Returns pv (pointer to virtual memory)

invoke Free, pv ; Ordinal COMCTL32.DLL:73
Returns Non-zero

invoke GetSize, pv ; Ordinal COMCTL32.DLL:74
Returns bytes allocated
Posted on 2004-07-26 21:29:56 by donkey
take a look at Matt Pietrek's "Secrets of Windows 95" book, the Delayload source (i have not been able to obtain a copy), but roughly, return an empty mapping:

	// In Windows 9X, create a small memory mapped file. On this platform, 

// memory mapped files are above 2GB, and thus are accessible by all
// processes.

HANDLE hFileMapping = CreateFileMapping (INVALID_HANDLE_VALUE, 0, PAGE_READWRITE | SEC_COMMIT, 0, size, 0);
return (void *) MapViewOfFile (hFileMapping, FILE_MAP_WRITE, 0, 0, size);

easy :)
and yes sorry for being lazy and not typing that in asm.
Posted on 2004-07-26 21:39:46 by Drocon
...or you could always have a look at how EliCZ does the stuff :)
Posted on 2004-07-26 23:12:35 by f0dder