Log in

View Full Version : Suspending a riot process..how?


Shub-nigurrath
February 21st, 2005, 08:20
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;
}


And then after an initial resume of the process, to skip the initial unpacking and wait the guard condition to come active (I wait a memory address assuming a specific value or the main program's window to appear). I do as following:

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;
}

}


then patch it using writememory..

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!

dELTA
February 21st, 2005, 11:12
As soon as you have resumed the thread the first time after the creation, it may create additional threads. These threads will still be running when you suspend the main thread the second time, and hence they may execute any code and modify anything in the memory space of the application. May that be it, or did I misunderstand anything?

evaluator
February 21st, 2005, 12:31
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..

nikolatesla20
February 23rd, 2005, 12:53
This is one good reason that a loader/unpacker SHOULD be a debugger, because ALL threads will freeze when they are being debugged, not to mention you can intercept CreateThreads then too - you can still hide the debugger if you know what API's and other techniques are being used to detect it, because the debugger can just intercept those techniques and modify the answer.

Like eval said one technique is ZWQueryInformationProcess (look that up in search on this board)

Another is checking the parent process's name (the app checks to make sure it's not being launched by anything but explorer)

Another is the common PIB flag for debugger (The flag that IsDebuggerPresent() actually uses internally)

All of these techniques can be found on the board.

I wrote an unpacker a while ago for SoftDefender that had to hide itself very well using all of these techniques combined....and did some other fancy stuff too (tricking SD into thinking it didn't need to launch another process, etc).

A Debugger process can emulate anything, it's just a matter of finding what it needs to do. What I've found as a good way to approach it is learn how to unpack the target manually, and then write the unpacker to do the same steps.

-nt20

Shub-nigurrath
February 23rd, 2005, 13:03
Hi,
I know what a debugger program can do and I agree with you at all.

I made the work on the program for which I made this post on the two different ways: with and without disturbing the debugging library .. and I managed them two to work with the same results. I did it for a tutorial I'm writing that will argue on the loaders and will present a c/c++ framework I wrote to create new loaders more easily..

Meanwhile between exetools and here I got my answers..

10x for your suggestions.