The previously-described method of insertion works only on Award and Phoenix, which is not good. There is a universal method compatible with all BIOS models, but this method is complex. The only location suitable for insertion is the boot block, or, to be more precise, the unconditional jump located at the F000h:FFF0h address.
Take any BIOS model and disassemble it. For clarity, I'll demonstrate the procedure on the example of AMI 6728 version 52 for the MSI 865PE Neo3-F motherboard. The firmware file is a6728ims.520. The fragment of its boot block is shown in Listing 32.12.
0007FD20: 80 00 00 00-00 31 49 38-36 35 78 78-78 00 00 00 1I865xxx 0007FD30: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00 ... 0007FF30: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00 0007FFE0: 31 49 38 36-35 58 58 58-00 00 00 00-00 00 00 00 1I865XXX 0007FFF0: EA CD FF 00-F0 31 31 2F-31 36 2F 30-34 00 FC 00 eIy ?11/16/04 u
Near the end of the boot block, there are approximately 200h zeros, which is enough for placing extra code there. Replace EA CD FF 00-F0 (jmp 0F000:0FFCD) with EA 30 7F 00 F0 (jmp 0F000:7F30), copy the custom code there to overwrite the zeros, and rejoice. In other firmware versions, these sequences might differ slightly; therefore, before insertion into BIOS the code must automatically find a long sequence of zeros near its end. This is a trivial task. Recomputing the checksum is more difficult. Different BIOS models store it in different locations. What is it possible to do? The checksum of the boot block equals zero, and this is required. Therefore, it is enough to compute the checksum of the inserted code and add 2 bytes to its end (for boot blocks; in contrast to ISA blocks, the checksum is computed in words, not in bytes). This ensures that its checksum is zero, in which case the checksum of the entire boot block also will be zero. Thus, there is no need to search for the original checksum.
What can be done with the boot block? At first glance, it seems that nothing can be done because no devices are initialized and memory is not prepared. Therefore, setting breakpoints won't produce any result, because it will be impossible to trap the interrupt vector. Is this an end to all of the hacker's plans? No, the work has just begun! As you know, every boot block partially initializes hardware, in particular, external firmware on the adapters. This is done when the main memory is ready for operation. In the case of AMI 6728, this construct is located at the 7078Dh offset from the start of the file (Listing 32.13).
0007078D: 26813F 55AA CMP w, ES:[BX], 0AA55 ; "?U" 00070792: 74 10 JE 0000707A4 -------- (7)
Thus, all the hacker needs to do is find the sequence that appears like 55AA 7x ?? (CMP XXX, AA55h) and replace 7x ?? with EB xx (JMP SHORT xxx, where xxx is the pointer to the code inserted into the boot block). Before overwriting 7x ??, it is necessary to save it in the inserted custom code. After doing this, it becomes possible to set the trap to the boot sector. Because the inserted code is located in BIOS in unpacked form, there is no need to huddle in the interrupt table. It is possible to redirect the INT 01h interrupt vector directly to BIOS.
It is possible to trap the INT 13h interrupt (and prevent it from being modified), keeping it in BIOS. What benefit can be obtained from doing this? Windows does not use INT 13h; therefore, the code will be active only at the initial stages of the system start-up. Nevertheless, it is possible to read and write to and from sectors. Is it necessary to write a custom file system driver? The situation is easy when dealing with FAT, but what should you do with NTFS? The solution is easy. The code might sequentially scan all sectors to find sectors containing the MZ signature in the beginning. If the PE signature follows the end of the EXE header, then this is a PE file and the code can insert its body into this file using any acceptable method. The best place for insertion is the PE header, because the file might be fragmented and it is not guaranteed that further sectors would belong to it rather than another file.
To ensure that the custom code gains control, it must infect as many files as possible. System files will be immediately healed by SFC, and all the other files will be repaired by an antivirus scanner. However, both SFC and antivirus software are normal executable files that start after the virus gains control. The virus can counteract all such programs, for example, by simply blocking their execution.