![]() |
|
|
|
#1
|
||||
|
||||
|
Suspending a riot process..how?
Hi,
I'm working on a patch of a program and writing a loader for it. But for it I have this problem: the SuspendThread won't suspend the thread. I launch the victim process using CreateProcess in suspended mode as: Code:
if( !::CreateProcess( victimFileName.c_str(), // No module name (use command line).
NULL, // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
NULL, // Set handle inheritance to FALSE.
CREATE_SUSPENDED, // suspended creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi ) // Pointer to PROCESS_INFORMATION structure.
)
{
MessageBox(NULL, GetLastErrorMsg().c_str(), MSG_CAPTION,
MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
return 1;
}
Code:
//Before patching the victim application it's better to suspend it..
//If we cannot for some protection suspend the application then
//a little of tentatives are tried:
//1. repeat several time SuspendThread (see comment below to see why)
//2. try to lower the priority
//3. try using the kernel counterparts zwSuspendThread and zwSuspendProcess
//4. open the process to get another process handle.
// If all these things fails then closes the patcher with an error!
if(SuspendThread(pi.hThread)==-1) {
//If the thread is making a kernel call, SuspendThread fails.
//An application may need to repeat the SuspendThread several times for it
//to succeed.
int trials_count=0;
BOOL skiptherest=FALSE;
while(trials_count<=MAX_SUSPENDTHREAD_TRIALS) {
if(SuspendThread(pi.hThread)!=-1) {
skiptherest=TRUE;
break;
}
trials_count++;
}
//Try to lower the the thread's priority.
if(!skiptherest) {
thPriority=GetThreadPriority(pi.hThread);
if(thPriority!=THREAD_PRIORITY_NORMAL)
SetThreadPriority(pi.hThread,THREAD_PRIORITY_NORMAL);
if(SuspendThread(pi.hThread)!=-1)
skiptherest=TRUE;
}
//Try suspending the process using kernel equivalent functions
NTSTATUS ret=0;
if(!skiptherest) {
ret=ZwSuspendThread(pi.hThread, NULL);
if(ret>0)
skiptherest=TRUE;
}
if(!skiptherest) {
ret=ZwSuspendProcess(pi.hProcess);
if(ret>0)
skiptherest=TRUE;
}
if(!skiptherest) {
HANDLE hProc=OpenProcess(PROCESS_ALL_ACCESS,FALSE, pi.dwProcessId);
if(hProc==NULL) {
MessageBox(NULL, GetLastErrorMsg().c_str(), MSG_CAPTION,
MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
return 1;
}
pi.hProcess=hProc;
bProcessOpened=TRUE;
NTSTATUS ret=ZwSuspendProcess(pi.hProcess);
if(ret>0)
skiptherest=TRUE;
}
if(!skiptherest) {
::MessageBox(NULL, GetLastErrorMsg().c_str(), MSG_CAPTION,
MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
return 1;
}
}
I don't know if all the tentatives are sensefull or not, but all fails as well as the simple SuspendThread. Anyway a simple SuspendThread has worked fine for all the loaders I wrote, this is the first time I cannot suspend the process at all. Any suggestion regarding this will be extremely welcome! 10x in advance!
__________________
Ŝħůb-Ňìĝùŕřaŧħ ₪) There are only 10 types of people in the world: Those who understand binary, and those who don't http://www.accessroot.com Last edited by Shub-Nigurrath; 02-21-2005 at 21:24. |
|
#2
|
|||
|
|||
|
Hi Shub-Nigurrath !
You can inject some call to GetLastErrorMsg() under the call to SuppendThread to determine the error, and post the error you got. Regards, TQN |
|
#3
|
||||
|
||||
|
Hi TQN,
I forgotten to post it: the error code is always this: 5, "Access denied".. I'm administrator of the machine. I never supposed that suspending a thread whould have required a granting..I tried to play a little with the SECURITY attributes of CreateProcess but none of them changes the final result.
__________________
Ŝħůb-Ňìĝùŕřaŧħ ₪) There are only 10 types of people in the world: Those who understand binary, and those who don't http://www.accessroot.com |
|
#4
|
|||
|
|||
|
Have you tried to assign yourself Debug-Privileges or to run the Loader as "SYSTEM" User?
|
|
#5
|
||||
|
||||
|
Hi,
with all the other processes/program it works perfectly so it's something related to this particular program indeed.. Olly btw is able to attach to the program so it is doing something different. i have not used debug APIs of course, but I would avoid using them if there are other option.. In case how can I do what you suggest?
__________________
Ŝħůb-Ňìĝùŕřaŧħ ₪) There are only 10 types of people in the world: Those who understand binary, and those who don't http://www.accessroot.com |
|
#6
|
|||
|
|||
|
wow, happy to reply to shub.
The pi.hThread you have is the primary thread of the process.
an idea : 1. the process (and so on, the primary thread) do CreateThread 2. In the primary thread, do ExitThread (or TerminateThread) 3. sure the pi.hThread will be inexistant ? To be sure : GetProcessIdOfThread(pi.hThread) or GetThreadID(pi.hThread) Sure you did it but have you tried ProcessExplorer from SysInternals to see more info on the progyy ? Name of the proggy to DIY ? Last edited by LaDidi; 02-21-2005 at 23:54. |
|
#7
|
||||
|
||||
|
humm good idea, indeed the program is closing itself to reopen under another process..so my handle was useless..now I open the process once I have the real window of the application.
Anyway the program is "Advanced Registry Doctor Professional" 4.1 build 5563 hxyp://www.elcor.net/ard.php it's almost finished except some details such these for side parts of the program..the program giving problems is RegBackup.exe, while instead the main program works perfectly with a loader..
__________________
Ŝħůb-Ňìĝùŕřaŧħ ₪) There are only 10 types of people in the world: Those who understand binary, and those who don't http://www.accessroot.com Last edited by Shub-Nigurrath; 02-22-2005 at 02:07. |
|
#8
|
||||
|
||||
|
oh God,
I now have this situation: in VC++ the loader works fine, even with no breakpoints (continuous execution), but externally I have this behaviour -the ProcessId is correctly found using the handle of the main process window, -then it's passed to OpenProcess, which returns NULL -the GetLastError message reports 0, "The operation completed succesfully"...????? this happens only when running outside VC++. Alternatively, always outside VC++, some times instead the OpenProcess returns a valid handle but zwSuspendProcess is unable to suspend it.. Another question, once I have the handle coming from OpenProcess how can I suspend the Thread? Now I'm using zwSuspendProcess() but seems to give some problems indeed.. any glue!?!?
__________________
Ŝħůb-Ňìĝùŕřaŧħ ₪) There are only 10 types of people in the world: Those who understand binary, and those who don't http://www.accessroot.com Last edited by Shub-Nigurrath; 02-22-2005 at 02:08. |
|
#9
|
||||
|
||||
|
would it be possible that the main thread creates a new thread (with new thread id of course) and then terminates itself so your handle isn't valid anymore?
|
|
#10
|
|||
|
|||
|
are you playng with SDprotector?
it creates threads with 'inherited' parameter & SuspendProcess can't suspend them.. on this case, seems you are creating non-debugged process, ye? but in case of DEBUG-flag, you need to awoid detection via ZwQueryInform.. ** i wrote this in your thread @ Woodman, but now will paste here, in case.. ** |
|
#11
|
||||
|
||||
|
Hi,
I investigated a little the program launches itself and then closes it passing a parameter to another program that then launches the original program again. Waiting for the main window's program I can corectly detect the correct processID, open it and then access to a valid handle, but the problem is that is won't still suspend itself. even if there's only one thread in the process and the processid is correct. I have a doubt that zwSuspendProcess how I implemented it might not be working correctly (I read it directly from ntdll). But I cannot find an API which allow to pass from hProcess to an hTread and then being able to use SuspendThread. Any suggestion?
__________________
Ŝħůb-Ňìĝùŕřaŧħ ₪) There are only 10 types of people in the world: Those who understand binary, and those who don't http://www.accessroot.com |
|
#12
|
|||
|
|||
|
Could the security descriptor of the created thread (by target)
have been defined to prevent suspend/resume? If so, possible to change objects access rights of spawned thread? -bg |
|
#13
|
|||
|
|||
|
We can use ToolHelp API with CreateToolhelp32Snapshot, ThreadFirst, ThreadNext, OpenThread... functions to obtain threadID, threadHandle of all threads in a process which have processID obtained from GetWindowThreadProcessId, OpenProcess.
Some threads have security descriptor which not allow SuspendThread, ResumeThread. We can use the Get/SetSecurityInfo functions to see and change security descriptor of those threads. |
|
#14
|
|||
|
|||
|
An other idea.
Thanks MARKuS to explain better my idea :-)
In fact, RegBackup launch the service RegManServ which launch another instance of RegBackup in a SYSTEM context ! Have you tried to launch via SYSTEM context (ie: AT HH:MM myProg.exe). You have RegManServ.Log which may help you... Effectively, it execs : "C:\app_test\Advanced Registry Doctor\RegBackup.exe" /INIT_DIR="c:\RegBackup\" /local_system ***** A part of the answer ***** As it Executes GlobalAddAtomA("RegManServRegBackup.exe") [see HW_BP in 00411986 or BP on ntdll.ZwAddAtom], it uses DDE !... |
|
#15
|
||||
|
||||
|
ah, TQN, this is exactly what I was looking at, I was hoping there was a simpler way to do it!
actually what I only need is to write something in the process's space. How Olly does to attach to a process? is there any readymade implementation of a function such for example Attach(processID) ?? Just to make it simple! :-) Moreover ZwSuspendProcess might work instead (even if it seems not to work for me)? 10x again to all of U.
__________________
Ŝħůb-Ňìĝùŕřaŧħ ₪) There are only 10 types of people in the world: Those who understand binary, and those who don't http://www.accessroot.com |
![]() |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| How RIOT Games employs anti cheat measures | foosaa | General Discussion | 0 | 07-18-2018 09:45 |
| Suspending Kernel Mode Threads... | omidgl | General Discussion | 10 | 01-17-2005 17:56 |