************************************* 
* Details of FrogsICE returned code * 
*************************************

Code 01 
=======

* * SOFTICE SHOULD NOT BE LOADED SO THAT FROGSICE CAN DETECT THIS METHOD * *

This method of detection of SoftICE (as well as the following one) is
used by the majority of packers/encryptors found on Internet.
It seeks the signature of BoundsChecker in SoftICE


    mov     ebp, 04243484Bh        ; 'BCHK'
    mov     ax, 04h
    int     3       
    cmp     al,4
    jnz     SoftICE_Detected

______________________________________________________________________________________________

Code 02
=======

* * SOFTICE SHOULD NOT BE LOADED SO THAT FROGSICE CAN DETECT THIS METHOD * *

Still a method very much used (perhaps the most frequent one).  It is used
to get SoftICE 'Back Door commands' which gives infos on Breakpoints,
or execute SoftICE commands...
It is also used to crash SoftICE and to force it to execute any commands (HBOOT...) :-((  
Here is a quick description:
-AX = 0910h   (Display string in SIce windows)
-AX = 0911h   (Execute SIce commands -command is displayed is ds:dx)
-AX = 0912h   (Get breakpoint infos)
-AX = 0913h   (Set Sice breakpoints)
-AX = 0914h   (Remove SIce breakoints)

Each time you'll meet this trick, you'll see:
-SI = 4647h
-DI = 4A4Dh
Which are the 'magic values' used by SoftIce.
For more informations, see "Ralf Brown Interrupt list" chapter int 03h.

Here is one example from the file "Haspinst.exe" which is the dongle HASP Envelope utility
use to protect DOS applications:


4C19:0095  B81109          MOV       AX,0911     ; execute command.
4C19:0098  8B17            MOV       DX,[BX]     ; ds:dx point to the command (see below).
4C19:009A  BE4746          MOV       SI,4647     ; 1st magic value.
4C19:009D  BF4D4A          MOV       DI,4A4D     ; 2nd magic value.
4C19:00A0  CC              INT       3           ; Int call.(if SIce is not loaded, jmp to 00AD)
4C19:00A1  83C302          ADD       BX,02       ; BX+2 to point to next command to execute
4C19:00A4  41              INC       CX
4C19:00A5  83F906          CMP       CX,06       ; Repeat 6 times  to execute
4C19:00A8  72EB            JB        0095        ; 6 different commands.
4C19:00AA  E955FF          JMP       0002        ; Bad_Guy jmp back.
4C19:00AD  8BDC            MOV       BX,SP       ; Good_Guy go ahead :)

The program will execute 6 different SIce commands located at ds:dx, which are:
LDT, IDT, GDT, TSS, RS, and ...HBOOT.


______________________________________________________________________________________________


Code 03
=======

Less used method.  It seeks the ID of SoftICE VxD via the int 2Fh/1684h (API Get entry point)
        

    xor     di,di
    mov     es,di
    mov     ax, 1684h       
    mov     bx, 0202h       ; VxD ID of winice
    int     2Fh
    mov     ax, es          ; ES:DI -> VxD API entry point
    add     ax, di
    test    ax,ax
    jnz     SoftICE_Detected

_______________________________________________________________________________________________

Code 04
=======

Method identical to the preceding one except that it seeks the ID of SoftICE GFX VxD.

    xor     di,di
    mov     es,di
    mov     ax, 1684h       
    mov     bx, 7a5Fh       ; VxD ID of SIWVID
    int     2fh
    mov     ax, es          ; ES:DI -> VxD API entry point
    add     ax, di
    test    ax,ax
    jnz     SoftICE_Detected

__________________________________________________________________________________________________


Code 05
=======

* * SOFTICE SHOULD NOT BE LOADED SO THAT FROGSICE CAN DETECT THIS METHOD * *


Method seeking the 'magic number' 0F386h returned (in ax) by all system debugger.
It calls the int 41h, function 4Fh.
There are several alternatives.  

The following one is the simplest:

    mov     ax,4fh
    int     41h
    cmp     ax, 0F386
    jz      SoftICE_detected


Next method as well as the following one are 2 examples from Stone's "stn-wid.zip" (www.cracking.net).
They are both a bit harder to detect but FrogsICE intercepts them without any problems
(again, as long as SoftICE is not loaded)

    mov     bx, cs
    lea     dx, int41handler2
    xchg    dx, es:[41h*4]     
    xchg    bx, es:[41h*4+2]
    mov     ax,4fh
    int     41h
    xchg    dx, es:[41h*4]
    xchg    bx, es:[41h*4+2]
    cmp     ax, 0f386h
    jz      SoftICE_detected

int41handler2 PROC
    iret
int41handler2 ENDP


________________________________________________________________________________________


Code 06
=======

* * SOFTICE SHOULD NOT BE LOADED SO THAT FROGSICE CAN DETECT THIS METHOD * *

2nd method similar to the preceding one but more difficult to detect:


int41handler PROC
    mov     cl,al
    iret
int41handler ENDP


    xor     ax,ax
    mov     es,ax
    mov     bx, cs
    lea     dx, int41handler
    xchg    dx, es:[41h*4]
    xchg    bx, es:[41h*4+2]
    in      al, 40h
    xor     cx,cx
    int     41h
    xchg    dx, es:[41h*4]
    xchg    bx, es:[41h*4+2]
    cmp     cl,al
    jnz     SoftICE_detected

________________________________________________________________________________________

Code 07
=======

Method of detection of the WinICE handler in the int68h (V86)

    mov     ah,43h
    int     68h
    cmp     ax,0F386h
    jz      SoftICE_Detected

=> it is not possible to set a BPINT 68 with softice but you can hook a 32Bit
   app like this:

   BPX exec_int if ax==68
   (function called is located at byte ptr [ebp+1Dh])
 (Client eip is located at [ebp+48h] for 32Bit apps, see frogsICE source)
___________________________________________________________________________________________


Code 08
=======

It is not a method of detection of SoftICE but a possibility to crash the system
by intercepting int 01h and int 03h and redirecting them to another routine.
It calls int 21h functions 25h and 35h (set/get int vector) and ds:dx points to the new
routine to execute (hangs computer...)
FrogsICE intercepts the set int vector call (function 25h)

    mov     ah, 25h
    mov     al, Int_Number (01h or 03h for FrogsICE)
    mov     dx, offset New_Int_Routine
    int     21h

===============================================================================================

Code 09
=======

This method is closed to methods 03 and 04 (int 2Fh/1684h) but it is only performed
in ring0 (VxD or a ring3 app using the VxdCall).
The Get_DDB service is used to determine whether or not a VxD is installed for the 
specified device and returns a Device Description Block (in ecx) for that device if it is installed.

   mov     eax, Device_ID        ; 202h for SICE or 7a5Fh for SIWVID VxD ID
   mov     edi, Device_Name      ; only used if no VxD ID (useless in our case ;-)
   VMMCall Get_DDB
   mov     [DDB], ecx            ; ecx=DDB or 0 if the VxD is not installed

When pressing the 'ESCAPE' key to fool the app, FrogsICE will simply clear ecx and return to the calling
program without chaining to the previous hook (no time to waste, windowz is slow enough ;-)

Note as well that you can easily detect this method with SoftICE as per follows:
   bpx Get_DDB if ax==0202 || ax==7a5fh

===============================================================================================

Code OA
=======

=>Disable or clear breakpoints before using this feature. DO NOT trace with SoftICE while
  the option is enable!!

This trick is not very used though it is very efficient:
by checking the Debug Registers, you can detect if SoftICE is loaded (dr7=0x700 if you loaded the
soft with SoftICE loader, 0x400 otherwise) or if there are some memory breakpoints set (dr0 to dr3)
simply by reading their value (in ring0 only). Values can be manipulated/changed as well (clearing
BPMs for instance)

The method used by FrogsICE to detect Debug Registers access is only available for 486i+ CPU,
because it sets the dr7 GD bit to enable breakpoint (int01h) on access. Then it reads the dr6 BD bit
to check if the next intruction is attempting to read/write a drX.

=>FrogsICE will NOT show the BleuScreenOfDeath while hooking debug registers. See FrogsICE.txt

______________________________________________________________________________________________

Code 0B
=======

This method is most known as 'MeltICE' because it has been freely distributed
via www.winfiles.com. However it was first used by NuMega people to allow Symbol
Loader to check if SoftICE was active or not (the code is located inside nmtrans.dll).

The way it works is very simple:
It tries to open SoftICE drivers handles (SICE, SIWVID for Win9x, NTICE for WinNT)
with the CreateFileA API.

Here is a sample (checking for 'SICE'):

BOOL IsSoftIce95Loaded()
{
   HANDLE hFile;  
   hFile = CreateFile( "\\\\.\\SICE", GENERIC_READ | GENERIC_WRITE,
                      FILE_SHARE_READ | FILE_SHARE_WRITE,
                      NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
   if( hFile != INVALID_HANDLE_VALUE )
   {
      CloseHandle(hFile);
      return TRUE;
   }
   return FALSE;
}

Although this trick calls the CreateFileA function, don't even expect to be able
to intercept it by installing a IFS hook: it will not work, no way!
In fact, after the call to CreateFileA it will get through VWIN32 0x001F service
(via Kernel32!ORD_0001/VxDCall function and int 30h) and then browse the DDB list
until it find the VxD and its DDB_Control_Proc field.
This VWIN32 function is undocumented.
In fact, its purpose is not to load/unload VxDs but only to send a W32_DEVICEIOCONTROL (0x23)
control message (DIOC_OPEN and DIOC_CLOSEHANDLE) to the VxD Control_Dispatch proc (how the hell
a shareware soft could try to load/unload a non-dynamically loadable driver such as SoftICE ;-).
If the VxD is loaded, it will always clear eax and the Carry flag to allow its handle to be opened
and then, will be detected.
You can check that simply by hooking Winice.exe control proc entry point while running MeltICE.
So as it needs to call the VMM_GetDDBList, FrogsICE hooks this function and check eax value
(saved on the stack at [esp+3ch] in W98 and [esp+48h] in W95) which contains the name of the
driver (SICE, SIWVID or NTICE).

=>FrogsICE will fetch the caller's name just to ensure it is not Loader32. If it is, it will not
  hook it.
=>the address cs:eip returned by FrogsICE is the location of the driver's name string reference
  inside your program (not the call to createfileA)
  example:
  00401067:  push      00402025    ; \\.\SICE
  0040106C:  call      CreateFileA
  00401071:  cmp       eax,-001
  00401074:  je        00401091

  FrogsICE will then return 'detection at cs:00402025'.

=>FrogsICE cannot be detected using this method ;-)

There could be hundreds of BPX you could use to detect this trick.
-The most classical one is:
   BPX CreateFileA if *(esp->4+4)=='SICE' || *(esp->4+4)=='SIWV' || *(esp->4+4)=='NTIC'

-The most exotic ones (could be very slooooow :-(
   BPINT 30 if eax==002A001 && (*edi=='SICE' || *edi=='SIWV')  ; will break 3 times :-(
-or (a bit) faster: 
   BPINT 30 if (*edi=='SICE' || *edi=='SIWV')

   BPX KERNEL32!ORD_0001 if *edi=='SICE' || *edi=='SIWV'       ; will break 3 times :-(

-Much faster:
   BPX VMM_GetDDBList if eax->3=='SICE' || eax->3=='SIWV'

______________________________________________________________________________________________

Code 0C
=======

This trick is similar to int41h/4fh Debugger installation check (code 05 & 06) 
but very limited because it's only available for Win95/98 (not NT) as it uses
the VxDCall backdoor. This detection was found in Bleem Demo.
FrogsICE doesn't hook the VWIN32_Int41Dispatch service but Exec_PM_Int as it is
the simplest and most efficient way to detect it.

   push  0000004fh         ; function 4fh
   push  002a002ah         ; high word specifies which VxD (VWIN32)
                           ; low word specifies which service (VWIN32_Int41Dispatch)
   call  Kernel32!ORD_001  ; VxdCall
   cmp   ax, 0f386h        ; magic number returned by system debuggers
   jz    SoftICE_detected

Here again, several ways to detect it:

    BPINT 41 if ax==4f

    BPINT 30 if ax==0xF386   ; SoftICE must be loaded for this one

    BPX Exec_PM_Int if eax==41 && edx->1c==4f && edx->10==002A002A

    BPX Kernel32!ord_0001 if esp->4==002A002A && esp->8==4f   ; slooooow!

______________________________________________________________________________________________

Code 0D  ** (new v0.40) **
=======

Not a real method of detection, but a good way to know if SoftICE is installed
on a computer and to locate its installation directory.
It is used by few softs which access the following registry keys (usually #2) :

- #1 : HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\SoftICE
- #2 : HKEY_LOCAL_MACHINE\Software\NuMega\SoftICE


=> As for the MeltICE trick (code 0B) the address cs:eip returned by FrogsICE is
   the location of the registry key string reference inside your program 
   (not the call to RegOpenKeyExA)

Note that some nasty apps could then erase all files from SoftICE directory (I faced
that once :-(


Useful breakpoint to detect it:

     BPX _regopenkey if *(esp->8+0x13)=='tICE' || *(esp->8+0x37)=='tICE'

______________________________________________________________________________________________

Code OE  ** (new v0.40) **
=======

This code is returned when an app tries to detect FrogsICE VxD via a call
to CreateFileA. 
Method used and returned values are the same as for the MeltICE detection.

The only difference is that FrogsICE will always fool the app (even if you patched
it with FPInstall to hide it from detection) to avoid a crash (FrogsICE would hook
itself :-(


______________________________________________________________________________________________
Frog's Print  November 99