using this scheme, only a serial-connection kernel debugger such as KD or
WinDbg. For a straightforward detection of SoftICE, it is possible to simply
check if the SoftICE kernel device is present. This can be done by opening a file
called “\\.SIWVID” and assuming that SoftICE is installed on the machine if
the file is opened successfully.
This approach of detecting the very presence of a kernel debugger is some-
what risky because legitimate users could have a kernel debugger installed,
which would totally prevent them from using the program. I would generally
avoid any debugger-specific approach because you usually need more than
one of them (to cover the variety of debuggers that are available out there), and
combining too many of these tricks reduces the quality of the protected soft-
ware because it increases the risk of false positives.
Detecting SoftICE Using the Single-Step Interrupt
This is another debugger-specific trick that I really wouldn’t recommend
unless you’re specifically concerned about reversers that use NuMega SoftICE.
While it’s true that the majority of crackers use (illegal copies of) NuMega Soft-
ICE, it is typically so easy for reversers to detect and work around this scheme
that it’s hardly worth the trouble. The one advantage this approach has is that
it might baffle reversers that have never run into this trick before, and it might
actually take such attackers several hours to figure out what’s going on.
The idea is simple. Because SoftICE uses int 1for single-stepping through
a program, it must set its own handler for int 1in the interrupt descriptor table
(IDT). The program installs an exception handler and invokes int 1. If the
exception code is anything but the conventional access violation exception
(STATUS_ACCESS_VIOLATION), you can assume that SoftICE is running.
The following is an implementation of this approach for the Microsoft C
compiler:
__try
{
_asm int 1;
}
__except(TestSingleStepException(GetExceptionInformation()))
{
}
int TestSingleStepException(LPEXCEPTION_POINTERS pExceptionInfo)
{
DWORD ExceptionCode = pExceptionInfo->ExceptionRecord->ExceptionCode;
if (ExceptionCode != STATUS_ACCESS_VIOLATION)
printf (“SoftICE is present!”);
return EXCEPTION_EXECUTE_HANDLER;
}
334 Chapter 10