; ; Derived from source code of TrueCrypt 7.1a, which is ; Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed ; by the TrueCrypt License 3.0. ; ; Modifications and additions to the original source code (contained in this file) ; and all other portions of this file are Copyright (c) 2013-2017 IDRIX ; and are governed by the Apache License 2.0 the full text of which is ; contained in the file License.txt included in VeraCrypt binary and source ; code distribution packages. ; .MODEL tiny .386 _TEXT SEGMENT USE16 INCLUDE BootDefs.i ORG 7C00h ; Standard boot sector offset start: ; BIOS executes boot sector from 0:7C00 or 7C0:0000 (default CD boot loader address). ; Far jump to the next instruction sets IP to the standard offset 7C00. db 0EAh ; jmp 0:main dw main, 0 loader_name_msg: db ' VeraCrypt Boot Loader', 13, 10, 0 main: cli xor ax, ax mov ds, ax mov ss, ax mov sp, 7C00h sti ; Display boot loader name test byte ptr [start + TC_BOOT_SECTOR_USER_CONFIG_OFFSET], TC_BOOT_USER_CFG_FLAG_SILENT_MODE jnz skip_loader_name_msg lea si, loader_name_msg call print skip_loader_name_msg: ; Determine boot loader segment mov ax, word ptr [ds:413h] ;available kB from BIOS sub ax, TC_BOOT_MEMORY_REQUIRED ;minus TC_BOOT_MEMORY_REQUIRED jc mem_toolow and ax, 0FFE0h ;32K align shl ax, 6 ;convert kB to segment addr (*1024/16) cmp ax, 8000h jb mem_toolow ;we can't load below 8000h cmp ax, TC_BOOT_LOADER_SEGMENT jbe memory_ok ;don't load above TC_BOOT_LOADER_SEGMENT (9000h) mov ax, TC_BOOT_LOADER_SEGMENT jmp memory_ok mem_toolow: mov ax, TC_BOOT_LOADER_LOWMEM_SEGMENT memory_ok: mov es, ax ; Clear BSS section xor al, al mov di, TC_COM_EXECUTABLE_OFFSET mov cx, TC_BOOT_MEMORY_REQUIRED * 1024 - TC_COM_EXECUTABLE_OFFSET - 1 cld rep stosb mov ax, es sub ax, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE / 16 ; Decompressor segment mov es, ax ; Load decompressor mov cl, TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR retry_backup: mov al, TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT mov bx, TC_COM_EXECUTABLE_OFFSET call read_sectors ; Decompressor checksum xor ebx, ebx mov si, TC_COM_EXECUTABLE_OFFSET mov cx, TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * TC_LB_SIZE call checksum push ebx ; Load compressed boot loader mov bx, TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET mov cl, TC_BOOT_LOADER_START_SECTOR mov al, TC_MAX_BOOT_LOADER_SECTOR_COUNT test backup_loader_used, 1 jz non_backup mov al, TC_BOOT_LOADER_BACKUP_SECTOR_COUNT - TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT mov cl, TC_BOOT_LOADER_START_SECTOR + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT non_backup: call read_sectors ; Boot loader checksum pop ebx mov si, TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET mov cx, word ptr [start + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET] call checksum ; Verify checksum cmp ebx, dword ptr [start + TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET] je checksum_ok ; Checksum incorrect - try using backup if available test backup_loader_used, 1 jnz loader_damaged mov backup_loader_used, 1 mov cl, TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT test TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE, byte ptr [start + TC_BOOT_SECTOR_CONFIG_OFFSET] jnz retry_backup loader_damaged: lea si, loader_damaged_msg call print lea si, loader_name_msg call print jmp $ checksum_ok: ; Set up decompressor segment mov ax, es mov ds, ax cli mov ss, ax mov sp, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE sti push dx ; Decompress boot loader mov cx, word ptr [start + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET] sub cx, TC_GZIP_HEADER_SIZE push cx ; Compressed data size push TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET + TC_GZIP_HEADER_SIZE ; Compressed data push TC_MAX_BOOT_LOADER_DECOMPRESSED_SIZE ; Output buffer size push TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE + TC_COM_EXECUTABLE_OFFSET ; Output buffer push cs push decompressor_ret push es push TC_COM_EXECUTABLE_OFFSET retf decompressor_ret: add sp, 8 pop dx ; Restore boot sector segment push cs pop ds ; Check decompression result test ax, ax jz decompression_ok lea si, loader_damaged_msg call print jmp $ decompression_ok: ; DH = boot sector flags mov dh, byte ptr [start + TC_BOOT_SECTOR_CONFIG_OFFSET] ; Set up boot loader segment mov ax, es add ax, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE / 16 mov es, ax mov ds, ax cli mov ss, ax mov sp, TC_BOOT_LOADER_STACK_TOP sti ; Execute boot loader push es push TC_COM_EXECUTABLE_OFFSET retf ; Print string print: xor bx, bx mov ah, 0eh cld @@: lodsb test al, al jz print_end int 10h jmp @B print_end: ret ; Read sectors of the first cylinder read_sectors: mov ch, 0 ; Cylinder mov dh, 0 ; Head ; DL = drive number passed from BIOS mov ah, 2 int 13h jnc read_ok lea si, disk_error_msg call print read_ok: ret ; Calculate checksum checksum: push ds push es pop ds xor eax, eax cld @@: lodsb add ebx, eax rol ebx, 1 loop @B pop ds ret backup_loader_used db 0 disk_error_msg db 'Disk error', 13, 10, 7, 0 loader_damaged_msg db 7, 'Loader damaged! Repair with Rescue Disk', 0 ORG 7C00h + 510 dw 0AA55h ; Boot sector signature _TEXT ENDS END start a id='n57' href='#n57'>57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215