;##########################################################################
    .386p
    .model flat, stdcall
    option casemap :none

    include Header.asm

    WM_SHELLNOTIFY equ WM_USER + 1

.data
    WindowTitle db "IceGhost", 0
    VxDName     db "\\.\iceghost.vxd", 0
    SorryNT     db "IceGhost has detected you are running WinNT or Win2K which are not supported.", 0
    ErrorVxD    db "Can't find IceGhost.vxd", 0
    ToolTip     db "SoftIce is now hidden", 0
    strExit     db "&Exit", 0
    idt         df 0
    int1        dq 0
    int3        dq 0
    mbcap       db 0

.data?
    hInstance   dd ?
    hWnd        dd ?
    hVxD        dd ?
    hMenu       dd ?
    Notify      NOTIFYICONDATA <>
    Cursor      POINT <>

.code
;##########################################################################
start:

    ;=============================
    ; CHECK FOR PREVIOUS INSTANCE
    ;=============================
    invoke SecondInstance, ADDR WindowTitle, ADDR WindowTitle
    .if eax != 0
        jmp quit
    .endif

    ;=====================
    ; EXIT IF NT DETECTED
    ;=====================
    invoke IsNT
    .if eax == TRUE
        invoke MessageBox, NULL,
                           ADDR SorryNT,
                           NULL,
                           MB_OK or MB_ICONEXCLAMATION
        jmp quit
    .endif

    ;===================================
    ; EXIT IF SOFTICE CAN'T BE DETECTED
    ;===================================
    invoke IsSoftIceRunning
    .if eax == FALSE
        jmp quit
    .endif

;=========== -BANG- =======================================================
; Made by:  r!sc 3rd Febuary 2000 /
; Visit:  http://csir.cjb.net    /
;================================
    sidt fword ptr [idt]
    mov     eax, dword ptr [idt+2]
    lea ebx, [eax+8]    ;address of int1 handler
    lea ecx, [eax+8*3]  ;address if int3 handler
    
    cli    
    mov esi,ebx     ; save int1
    lea edi, int1
    movsd
    movsd
    mov esi, ecx    ; save int3
    movsd
    movsd


    mov eax, dword ptr [int1+4]
    mov ax, word ptr [int1]
    mov edx, dword ptr [int3+4]
    mov dx, word ptr [int3]

    push edx
    sub edx,eax ; little check before we seriously screw up
    cmp dl,10h  ; dl==10h == winice isnt here? or already patched?
    je  exit
    pop edx
    

    mov edi, dword ptr [idt+2]
    add edi, 0b00h  ; gonna be horrid to your PC . 
                    ; and stamp two jumps into your IDT
    
    lea esi, [edi+5]
    mov byte ptr [edi],0e9h    
    sub eax, esi   
    mov dword ptr [edi+1],eax

    mov byte ptr [edi+10h],0e9h
    lea esi, [edi+15h]
    sub edx, esi
    mov dword ptr [edi+11h],edx
    ; maybe edi points to jmp int1
    ; & edi+10h points to jmp int3


    mov eax, edi    ; eax==newint1 , edx==newint3 (10h bytes apart..)
    lea edx, [eax+10h]

    cli             ;? dunno how often im supposed to use this
    mov [ebx], ax   ; stamp new int handler into idt
    shr eax,10h
    mov [ebx+6],ax
   
    mov [ecx],dx
    shr edx,10h
    mov [ecx+6],dx
    pushad
;============================= END OF BANG ================================
exit:
    invoke GetModuleHandle, NULL
    mov hInstance, eax
    LoadVxD ADDR VxDName
    .if eax == 0
        invoke MessageBox, NULL,
                           ADDR ErrorVxD,
                           NULL,
                           MB_OK or MB_ICONEXCLAMATION
        jmp quit
    .endif
    
    invoke WinMain, hInstance, NULL, 0, SW_SHOWDEFAULT
    UnloadVxD hVxD
quit:    
    invoke ExitProcess, 0
;==========================================================================
WinMain PROC    hInst   :DWORD,
                Msg     :DWORD,
                wParam  :DWORD,
                lParam  :DWORD

    LOCAL wMsg      :MSG    

    ;===================
    ; CREATE THE WINDOW
    ;===================
    invoke MakeWindow, ADDR WindowTitle,
                       ADDR WindowTitle,
                       0,
                       0, 0, 32, 32,
                       ADDR WinProc,
                       hInst,
                       0,
                       NULL
    mov hWnd, eax

    ;======================
    ; CREATE THE TRAY ICON
    ;======================
    mov Notify.cbSize, sizeof NOTIFYICONDATA
    m2m Notify.hwnd, hWnd
    mov Notify.uID, 1
    mov Notify.uFlags, NIF_ICON or NIF_MESSAGE or NIF_TIP
    mov Notify.uCallbackMessage, WM_SHELLNOTIFY
    invoke LoadIcon, hInstance, 2
    mov Notify.hIcon, eax
    lea ebx, Notify.szTip
    lea eax, ToolTip
    CopyMemory ebx, eax, 22
    invoke Shell_NotifyIcon, NIM_ADD, ADDR Notify

    ;=======================
    ; CREATE THE POPUP MENU
    ;=======================
    invoke CreatePopupMenu
    mov hMenu, eax
    invoke AppendMenu, hMenu, MF_STRING, 1, ADDR strExit

    ;==============
    ; MESSAGE LOOP
    ;==============
    .while TRUE
        invoke PeekMessage, ADDR wMsg, NULL, 0, 0, PM_REMOVE
        .if eax != 0
            mov eax, wMsg.message
            .if eax == WM_QUIT
                xor eax, eax
                ret
            .endif
            invoke TranslateMessage, ADDR wMsg
            invoke DispatchMessage, ADDR wMsg
        .endif
    .endw

    xor eax, eax
    ret
WinMain ENDP
;==========================================================================

WinProc     PROC        hWindow         :DWORD,
                        Msg             :DWORD,
                        wParam          :DWORD,
                        lParam          :DWORD

    invoke DefWindowProc, hWindow, Msg, wParam, lParam
    .if Msg == WM_SHELLNOTIFY
        .if lParam == WM_RBUTTONDOWN
            invoke GetCursorPos, ADDR Cursor
            invoke SetForegroundWindow, hWindow
            invoke TrackPopupMenu, hMenu, TPM_RIGHTALIGN, Cursor.x, Cursor.y, 0, hWindow, NULL
            invoke PostMessage, hWnd, WM_MOUSEMOVE, 0, 0
        .endif
    .elseif Msg == WM_COMMAND
        .if wParam == 1
            invoke DestroyWindow, hWindow
        .endif
    .elseif Msg == WM_DESTROY
        ;=======================
        ; CLOSE THE APPLICATION
        ;=======================
        invoke Shell_NotifyIcon, NIM_DELETE, ADDR Notify
        invoke PostQuitMessage, 0
    .endif

    ret
WinProc ENDP
;##########################################################################
end start