PDA

View Full Version : a SetThreadContext & ERROR_NOACCESS problem


garph0
December 13th, 2000, 05:27
Hi all
I'm here again with a question about my code injector tool:
the 'static' version (which Creates the process suspended and works on it befor letting it run) works (almost) well, so i decided to move on a dynamic version, which should attach to running processes.
The steps are almost the same, i'll repeat here so you'll haven't to read from previous posts:
1) Retrieve Thread and process handles (well, actually i obtain it from CreateProcess, but i don't use the CREATE_SUSPENDED)
2) SuspendThread()
3) Prepare a Shared Memory Mapped File with my new code, a page of the code found at entry point, some code to put back the original code back, and the code for a second thread (more on this later)
4) GetThreadContext and save it in the MMF, say MMFContext
5) Overwrite the target program entry point with the code to map the MMF and jump to the Injected code start
6) Create a duplicate of the target process main thread handle and save it in MMFhThread in the MMF
7) Modify the Eip in the context to the target program entry point
8) Resume the thread

when resumed the target program will map the MMF, execute the some code, execute the code in MMF to restore program's EP, then Create a new thread and enter in an endless loop.

the new thread will use the MMFhThread to
1) Suspend the main thread
2) restore it context <-------------- ERROR
3) resume the main thread

on step 2), SetThreadContext return FALSE, and GetLastError() tells ERROR_NOACCESS, which is the mapping of STATUS_ACCESSVIOLATION.
the documentation says:

Windows NT/ 2000: The handle must have the THREAD_SET_CONTEXT access right to the thread. For more information, see Thread Security and Access Rights.

I've not tested it under win98 (i will ), but when duplicating the handle i have requested THREAD_ALL_ACCESS and the operation completed successfully, so it shouldn't be a problem of privileges...

i'm pretty confused, do you ppl have any idea ?

thanks

garph0

NicoDE
December 13th, 2000, 08:36
It's seems to be a problem with DuplicateHandle.
You should use DUPLICATE_SAME_ACCESS in dwOption and leave dwDesiredAccess blank - so you can be sure to copy the _same_ rights.
I believe THREAD_ALL_ACCESS alone is not enough and PROCESS_VM_OPERATION / PROCESS_VM_WRITE is needed (API intern) to set the context of an thread.
Last but not least, are you sure that the handle is copied to right process (handle table) ?

Nico_

The Owl
December 13th, 2000, 08:44
i'm not too familiar with the NT security system, but what i know from others is that having the privilege to do something does not mean that it is actually enabled. eg: the admin user normally has shutdown privilege but unless it is explicitly enabled by a thread running in the admin user's context, the thread won't be able to initiate a shutdown. this is the reason why uninstallers do something like this on NT:

GetCurrentProcess
OpenProcessToken
LookupPrivilegeValueA("SeShutdownPrivilege"
AdjustTokenPrivileges
ExitWindowsEx

of course, the scheme applies to all the other possible privileges as well.

garph0
December 13th, 2000, 18:52
ok thanks ppl, i'll try if i'm missing something around here and i'll tell you

_but_ SuspendThread() works where SetThreadContext() fails, i'm not sure if it's an useful info

best regards

garph0

garph0
December 14th, 2000, 03:46
ok, now SetThreadContext() is working 8-D
thanks to The Owl and NicoDE
it was a matter of Context structure alignment in memory, and i've been confused from this:

INFO: Mapping NT Status Error Codes to Win32 Error Codes

WINDOWS NT STATUS CODE WIN32 ERROR CODE
------------------------------------------------------------------
STATUS_DATATYPE_MISALIGNMENT ERROR_NOACCESS
STATUS_ACCESS_VIOLATION ERROR_NOACCESS

i thought of access violation while the structure was misaligned regardless of ALIGN DWORD directive ('cause it's buried in the code)

bien, now I've got a new problem, but still not a new question (i don't know what is going wrong): as soon as i resume the primary thread and terminate the secondary one i get this situation:

1) the secondary thread terminates
2) the primary thread runs for a little (it always seems to start from something like ntoskrn!ExUnexpectedInt (i'm not sure of the name, but it sounds like this) ), then it dies (cleanly)

bye all

garph0