| [ Team LiB ] |
|
12.15 Detecting SoftICE12.15.1 ProblemSoftICE is a ring0 debugger that cannot be detected using standard debugger detection techniques. 12.15.2 SolutionNumega's SoftICE debugger is a kernel-mode debugger intended for debugging device drivers and Windows itself. It is favored by software protection crackers because of its power. Four well-known methods for detecting the presence of SoftICE exist, which are detailed in Section 12.15.3. 12.15.3 DiscussionThe "Meltice" technique is one of the oldest methods for detecting SoftICE. It attempts to open virtual devices created by SoftICE; if any of these devices exist, the debugger is present. #include <windows.h>
BOOL spc_softice_meltice(void) {
HANDLE hFile;
hFile = CreateFile(TEXT("\\.\\SICE"), GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
if (hFile = = INVALID_HANDLE_VALUE)
hFile = CreateFile(TEXT("\\.\\NTICE"), GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
if (hFile = = INVALID_HANDLE_VALUE)
hFile = CreateFile(TEXT("\\.\\SIWDEBUG"), GENERIC_READ, 0, 0,
OPEN_EXISTING, 0, 0);
if (hFile = = INVALID_HANDLE_VALUE)
hFile = CreateFile(TEXT("\\.\\SIWVID"), GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
if (hFile = = INVALID_HANDLE_VALUE) return FALSE;
CloseHandle(hFile);
return TRUE;
}
SoftICE provides an interface via the debug breakpoint (int3) instruction that allows a process to communicate with the debugger. By loading a magic value ("BCHK") into the ebp register and executing an int3, the Boundschecker (originally the Numega Boundschecker utility) interface can be accessed. The function to be called is loaded into the eax register; function 4 will set the al register to 0 if SoftICE is present. #include <windows.h>
_ _declspec(naked) BOOL spc_softice_boundschecker(void) {
_ _asm {
push ebp
mov ebp, 0x4243484B ; "BCHK"
mov eax, 4 ; function 4: boundschecker interface
int 3
test al, al ; test for zero
jnz debugger_not_present
mov eax, 1 ; set the return value to 1
pop ebp
ret
debugger_not_present:
xor eax, eax ; set the return value to 0
pop ebp
ret
}
}
The int3 interface can also be used to issue commands to SoftICE by setting the esi and edi registers to magic values, then invoking function 0x911: #include <windows.h>
char *sice_cmd = "hboot";
BOOL spc_softice_command(char *cmd) {
_ _asm {
push esi
mov esi, 0x4647 ; "FG"
push edi
mov edi, 0x4A4D ; "JM"
push edx
mov edx, [cmd] ; command (string) to execute
mov ax, 0x0911 ; function 911: execute SOFTICE command
int 3
pop edx
pop edi
pop esi
}
}
Finally, the presence of SoftICE can be detected by invoking function 0x43 of interrupt 0x68: #include <windows.h>
_ _declspec(naked) BOOL spc_softice_ispresent(void) {
_ _asm {
mov ah, 0x43
int 0x68
cmp ax, 0xF386
jnz debugger_not_present
mov eax, 1
ret
debugger_not_present:
xor eax, eax
ret
}
}
SoftICE detection and counterdetection is a continuously evolving field. Different versions of SoftICE have different memory footprints and runtime behavior that can be used to detect them; however, because most software protection crackers have modified their versions of SoftICE to foil known detection methods, it is advisable not to rely entirely on SoftICE detections for protection. 12.15.4 See Also
|
| [ Team LiB ] |
|