Reversing : The Hacker's Guide to Reverse Engineering

(ff) #1

SoftICE’s Disappearance


The first call being made in this sequence is again to NtDelayExecution, but
here you run into a little problem. When we hit F10 to step over the call to
NtDelayExecutionSoftICE just disappears! When you look at the Com-
mand Prompt window, you see that Defender has just exited and that it hasn’t
printed any of its messages. It looks like SoftICE’s presence has somehow
altered Defender’s behavior.
Seeing how the program was calling into NtDelayExecutionwhen it
unexpectedly disappeared, you can only make one assumption. The thread
that was created earlier must be doing something, and by relinquishing the
CPU Defender is probably trying to get the other thread to run. It looks like
you must shift your reversing efforts to this thread to see what it’s trying to do.

Reversing the Secondary Thread


Let’s go back to the thread creation code in the initialization routine to find out
what code is being executed by this thread. Before attempting this, you must
learn a bit on how NtCreateThreadworks. Unlike CreateThread, the
equivalent Win32 API, NtCreateThread is a rather low-level function.
Instead of just taking an lpStartAddressparameter as CreateThread
does, NtCreateThread takes a CONTEXT data structure that accurately
defines the thread’s state when it first starts running.
ACONTEXTdata structure contains full-blown thread state information.
This includes the contents of all CPU registers, including the instruction
pointer. To tell a newly created thread what to do, Defender will need to ini-
tialize the CONTEXTdata structure and set the EIPmember to the thread’s
entry point. Other than the instruction pointer, Defender must also manually
allocate a stack space for the thread and set the ESPregister in the CONTEXT
structure to point to the beginning of the newly created thread’s stack space
(this explains the NtAllocateVirtualMemorycall that immediately pre-
ceded the call to NtCreateThread). This long sequence just gives you an
idea on how much effort is saved by calling the Win32 CreateThreadAPI.
In the case of this thread creation, you need to find the place in the code
where Defender is setting the Eipmember in the CONTEXTdata structure.
Taking a look at the prototype definition for NtCreateThread, you can see
that the CONTEXTdata structure is passed as the sixth parameter. The function
is passing the address [EBP-310]as the sixth parameter, so one can only
assume that this is the address where CONTEXTstarts. From looking at the def-
inition of CONTEXTin WinDbg, you can see that the Eipmember is at offset
+b8. So, you know that the thread routine should be copied into [EBP-258]
(310 – b8 = 258). The following line seems to be what you’re looking for:

MOV DWORD PTR SS:[EBP-258],Defender.00402EEF

396 Chapter 11

Free download pdf