Award BIOS Patching
1. Introduction
Welcome to another article written by me, Pinczakko (^__^). It's a follow up from my other BIOS articles. This article explains the trick to patch the Award system bios a.k.a original.tmp with the help of only these tools:
Modbin 4.50.80C. This version of modbin works for award BIOS version 4.5xPG. It will be called as modbin throughout this article, unless otherwise stated.
HexWorkshop 4.23. This is a hexeditor, you can use whatever hexeditor you please.
IDA Pro disassembler. Used to analyze the system BIOS and find unique byte patterns (assembly instruction patterns) to be used for patching.
All of the aforementioned tools are running within Windows XP service pack 2.
The primary purpose of this BIOS modification trick is to avoid the use of third-party Award BIOS modification tools. Namely, BIOS modification tools such as awardmod or awardbios-editor (awdbedit). Some might ask why we have to avoid those tools? actually we don't have to avoid them. But, based on my experience, it's faster to carry out Award BIOS modification without those tools. That's all. Anyway, This trick can be extended to another BIOS code injection technique or another kind of modification techniques. The possibility is limitless, just use your imagination ;-).
You have to note that the trick explained here has only been tested and works successfully on award version 4.51PGNM bios, i.e. VD30728.bin (256KB), the latest version of BIOS for Iwill VD133 motherboard. Thus, proceed at your own risk if you eager to try it. You have been warned.
This article will be hard to grasp if you haven't done any BIOS modification before, particularly Award BIOS. So, please help yourself in that case. I've made couple of preliminary articles in this website in case you wonder where to start. They are provided in the list below in a systematic manner. It's better to read them sequentially as presented below to maximize your understanding.
[1] Advanced Award Bios v4.51PG Hacking Tutorial. The article explains the basics and also can be regarded as one of the ancestor of the technique presented here.
[2] Pinczakko's Guide to Award Bios Reverse Engineering. The article is very fundamental in BIOS reverse engineering discipline. You have to read it to become acquainted with everything I'm talking about in this article.
[3] Award BIOS code injection. The article explains how to inject your code to Award BIOS binary. It's also important to read to become acquainted with the BIOS code injection technique. It's a compliment to the technique presented here.
Once you've grasped the articles in the points above, just proceed accordingly. I guarantee you won't be confused in anyway, he..he..he.. :p
Allright. Since I'm an avid manga reader (Naruto manga), I will use some "manga derived terms" in this article for my reading pleasure codenamed Pinczakko ™ naming convention. I'll provide you with the dictionary first hand, so you won't get lost. Enjoy ;-).
Ninjutsu. It means problem-solving technique that need some level of comprehension to be able to use it and its primary purpose is to attack a problem in a quite general way.
Taijutsu. It means a special technique to speed-up the problem-solving process in which the algorithm that will lead to a solution is already known but it's tedious or will take a long time to accomplish.
Kinjutsu. It means forbidden technique. This kind of technique is technique that has high risk, not well researched yet. In most cases, kinjutsu is an expert level technique that will be very easily result in system crash if not used carefully. But, it's also have a big potential to be a powerful technique as time goes on.
Sharingan. It means binary-file speed-reading technique. It's particularly used for binary/hex files so that one can grasp the structure of particular binary file or to spot interesting parts of binary file. It's one form of ninjutsu.
Note that not all of the types of jutsu/technique mentioned above will be presented in this article. It depends on the circumstances. But, all of them eventually will show up in my later arcticles. Have phun (^__^).
2. Modbin Internals
During modbin's execution, when we started to modify the BIOS binary that's currently opened, modbin will generate 2 temporary files, i.e. BIOS.ROM and ORIGINAL.TMP. These are the details:
BIOS.ROM is the compressed version of last 128KB of the BIOS file. It contains the compressed ORIGINAL.TMP, the bootblock and the decompression block.
ORIGINAL.TMP is the decompressed system BIOS.
These temporary files are created within the directory of the modbin's executable. Below is a screenshot showing how it works.
3. System-BIOS Patching Ninjutsu
As mentioned in section 2, modbin creates temporary BIOS.ROM and ORIGINAL.TMP during its execution. Thus, during the existence of these temporary files, we can edit the temporary ORIGINAL.TMP. The net effect of modifying this binary will be applied to the overall BIOS binary when we exit modbin and save all the changes. Modbin is working under the hood to compress the modified temporary original.tmp into the BIOS binary that you saved. Now, can you see the pattern? It is a neat way to modify the system BIOS without relying to "third party" BIOS modification tools such as Award BIOS Editor, awardmod, etc.! We don't have to worry about the checksums either, since modbin will fix it for us. Below is a system-BIOS modification ninjutsu that I've tested and works flawlessly:
Open the BIOS binary to be patched with modbin.
Open the temporary ORIGINAL.TMP that is generated by step a in hexeditor and subsequently patch it with the hexeditor. At this point, one can also copy the decompressed system BIOS to another directory to be examined with disassembler. Remember that at this point modbin must stays open/active.
Save the changes and close modbin.
This ninjutsu works perfectly as expected in my experiments.
3.1. The Secret Of The Sharingan
As expected, the next ninjutsu that we have to master is the ninjutsu to disassemble ORIGINAL.TMP to find the routine that we want to patch. Certainly, IDA Pro is one of our ultimate arsenal to do this. However, we need more than just arsenal to accomplish this mission, we also need a neat ninjutsu. That ninjutsu is called sharingan.To put simply, sharingan is the ninjutsu to recognize a unique byte pattern within a binary file for certain purpose(s). Why would we need a unique byte pattern? It's because, with that information, we can recognize a procedure that is "interesting" to us in many similar binary files at one shot. For example, we can find the same procedure within the system BIOS for a few different mainboards that have the same type of BIOS, e.g. the same Award BIOS version. Mastering the concept of sharingan is very important, not only to this particular BIOS problem. It can be used in many other field (use your imagination for that). That's why it deserved its own section.
3.1.1. Byte Patterns a.k.a Signatures of Binary Files
We might be tempted to think that it's very hard to find pattern on binary file with 256 possible combination per byte. This fact may holds true to some degree. However, BIOS binary contains more code than data section, eventhough they are overlapped. Thus, finding a byte pattern is quite easy, since x86 code (its instruction bytes) has particular rules that must be adhered to. Just like other processor architectures. In addition, it's very natural not to waste precious space in the memory (RAM and BIOS chip) by repeating the same group of instructions/machine-codes over and over again. This space-saving technique is accomplished by forming a procedure/routine for group of instruction that will be invoked from another section of the binary. This last fact leave us with the huge possibility to find unique group of instructions (thus, a byte pattern) within the binary since they are rarely repeated (the same procedure is rarely repeated in the binary, only being called from another section). This byte pattern sometimes called signature.
The task of forming a new signature is not too hard, these are the "algorithm":
Find the procedure that is "interesting" with disassembler.
Observe the instruction groups that make up the procedure and note their equivalent hex values.
Get some bytes (a few instructions lumped as a group) as the "initial guess" for the signature. Search other posibility of occurence of the "initial guess" in the binary with hexeditor. If the occurence is more than one, add some more instruction bytes into the "initial guess" and repeat until only one occurence is found in the binary. Voila, the signature is formed.
Once we formed the signature, the task of patching a system BIOS file is an easy task. We can even build a "patcher" to automate the process (^__^).
Nevertheless, we can also note the mapping between the location of the code as seen in the disassembler and its hex values shown in the hexeditor to locate certain procedure. But, very often this method is too laborious (-_-).
3.1.2. Attacking With Sharingan
Contrary to the ordinary sharingan in the Naruto manga, our sharingan attacks without using genjutsu type technique, he..he..he.. . OK, enough with the manga thingie. Let's get back to our business.
Attacking with sharingan is not as easy as one might think. It needs a quite deliberate background on the subject that we are targeting. To be able to locate some delicate procedure that we want to patch, we have to know something about it to make an intelligent guess about its location. In windows binary file, a call to certain operating system function is the hint that we need. But, what about BIOS binary? Well, these are the tips:
If we are looking for an I/O related procedure, then we have to start looking for "suspicious" access to the particular I/O port. It's better to know the protocol that supposed to be used by the I/O port in advance. For example: if we want to find the chipset initialization routine, then we have to start looking for accesses to the PCI configuration address port and data port (port CF8h-CFBh and port CFCh-CFFh) due to access to the chipset is through PCI configuration cycles.
Some devices are mapped to some predefined address space, such as the VGA frame buffer is mapped to B_0000h or B_8000h. These quirks are something that we have to know.
In principle, we have to know the big picture and then narrowing the target in each step. For BIOS binary, in most cases we have to particularly aware of the hardware protocol that we are targeting and the address range (memory or I/O) that relates to the protocol. Once the protocol is known, we can look for the procedure quite easily, since the BIOS routines will be the implementation of the protocol, perhaps with only modest modification from the samples in the protocol documention ;-).
Grasping the concept of sharingan need some serious practice. Thus, the next subsections will show us some signatures in the system BIOS and the method used to find and to patch it.
3.2. Case 1: Sharingan Attack to The EPA Procedure
This sub-section is only a warming up. Don't get too excited yet :p. The EPA procedure in award BIOS is a quite a well-known procedure. Thus, the signature is already quite widespread on the net ;-).
In my BIOS, to modify the EPA Procedure, we can look for the "80 8EE1 0110 F646 1430" byte pattern, i.e.
Hex values Assembly Code
80 8E E1 01 10 or byte ptr [bp+1E1h], 10h
F6 46 14 30 test byte ptr [bp+14h], 30h
and subsequently patch it, as ilustrated in the BIOS modification change log below.
Changes in VD30728X.BIN:
source file name : VD30728B.BIN
modified file name : VD30728X.BIN
Modification goal: This modification supposed to disable the EPA Procedure completely.
Before modification the code looks like (disassembled original.tmp):
.........
E000:1E4C B8 00 F0 mov ax, 0F000h
E000:1E4F 8E D8 mov ds, ax
E000:1E51 assume ds:_F000h
E000:1E51 E8 8C 11 call exec_nnoprom_100h
E000:1E54 73 03 jnb short skip_epa_proc
E000:1E56 E8 C3 00 call EPA_Procedure
E000:1E59 skip_epa_proc: ; CODE XREF: POST_12S+8C
E000:1E59 E8 AF 01 call init_EGA_video
.........
E000:1F1C EPA_Procedure proc near ; CODE XREF: POST_12S+8E
E000:1F1C 80 8E E1 01 10 or byte ptr [bp+1E1h], 10h
E000:1F21 F6 46 14 30 test byte ptr [bp+14h], 30h
E000:1F25 74 01 jz short loc_E000_1F28
E000:1F27 C3 retn
E000:1F28 ; ---------------------------------------------------------------------------
E000:1F28 loc_E000_1F28: ; CODE XREF: EPA_Procedure+9
E000:1F28 06 push es
.........
After modification the code looks like (disassembled original.tmp):
.........
E000:1E4C B8 00 F0 mov ax, 0F000h
E000:1E4F 8E D8 mov ds, ax
E000:1E51 assume ds:nothing
E000:1E51 90 nop
E000:1E52 90 nop
E000:1E53 90 nop
E000:1E54 90 nop
E000:1E55 90 nop
E000:1E56 90 nop
E000:1E57 90 nop
E000:1E58 90 nop
E000:1E59 E8 AF 01 call init_EGA_Video
.........
Testing result: Goal reached, the BIOS doesn't display EPA Logo as intended and the system still works normally.
If you want to try this modification yourself, patch the highlighted instructions by using hexeditor to NOP (90h) as shown above. In this sample, the signature is already known in advance. Hence, we have no difficulty to carry-out the modification.
3.3. Case 2: Sharingan Attack to The Clock Generator Initialization Routine
In this second modification round, we will try to disable/deactivate one of the clock-line output from the clock generator chip. These are details of the modification:
source file name : VD30728B.BIN
modified file name : VD30728X.BIN
Modification goal: This modification supposed to disable/deactivate one of the clock-line output from the clock generator chip.
This case is more difficult than the previous one since hints about our target are rare at best. These are the facts that we know:
Clock generator chip usually accessed through I2C/SMBus interface.
Clock generator initialization is carried out along with the FSB initialization. Thus, the routine very possibly located near some kind of CPU initialization routine.
If the clock generator datasheet is avaliable, then we can speed-up searching the related routines. Unfortunately, this is not the case for my motherboard. Thus, we can only guess about it.
The first step is to disassemble the BIOS and follow the POST_Jump_Table as described in [2]. We look for the CPU initialization routine from the POST_Jump_Table. I found it at POST_9S as follows (disassembled original.tmp):
E000:61C2 Begin_E000_POST_Jmp_Table
E000:61C2 4E 15 dw 154Eh ; restore warm-boot flag
E000:61C4 6F 15 dw 156Fh ; dummy
E000:61C6 71 15 dw 1571h ; initialize KBC (Keyboard Controller), halt on error
E000:61C8 D2 16 dw 16D2h ; 1. check Fseg in RAM, beep on-error;
E000:61C8 ; 2. identify FlashROM chip
E000:61CA 45 17 dw 1745h ; chk CMOS circuit
E000:61CC 8A 17 dw 178Ah ; Chipset reg Default values (code in awardext.rom, data in Fseg)
E000:61CE 98 17 dw 1798h ; 1. init CPU Flags
E000:61CE ; 2. disable A20
E000:61D0 B8 17 dw 17B8h ; 1. init interrupt vector
E000:61D0 ; 2. initialize "signatures" used for Ext_BIOS components
E000:61D0 ; decompression.
E000:61D0 ; 3. init PwrMgmtCtlr
E000:61D2 4B 19 dw 194Bh ; 1. init FPU <<========================================
E000:61D2 ; 2. init microcode (init CPU)
E000:61D2 ; 3. init FSB (clock gen)
E000:61D2 ; 4. init W87381D VID regs .........
E000:194B POST_9S proc near
E000:194B 1E push ds
E000:194C 80 66 3D FE and byte ptr [bp+3Dh], 0FEh
E000:1950 E8 F1 00 call call_init_FPU
E000:1953 B8 00 00 mov ax, 0
E000:1956 8E D8 mov ds, ax
E000:1958 assume ds:nothing
E000:1958 8A 46 3D mov al, [bp+3Dh]
E000:195B A2 B4 04 mov ds:byte_0_4B4, al
E000:195E BE 18 08 mov si, 818h
E000:1961 E8 1A 53 call F0_Setup_BIOS_Defaults?
E000:1964 0A C0 or al, al
E000:1966 74 05 jz short next
E000:1968 80 0E BA 04 80 or ds:byte_0_4BA, 80h
E000:196D next: ; CODE XREF: POST_9S+1B
E000:196D BE 95 08 mov si, 895h
E000:1970 E8 0B 53 call F0_Setup_BIOS_Defaults?
E000:1973 0A C0 or al, al
E000:1975 74 05 jz short next_
E000:1977 80 0E AC 04 10 or ds:byte_0_4AC, 10h
E000:197C next_: ; CODE XREF: POST_9S+2A
E000:197C F6 46 10 0F test byte ptr [bp+10h], 0Fh
E000:1980 74 13 jz short _next_
E000:1982 80 4E 14 40 or byte ptr [bp+14h], 40h
E000:1986 BE 4A 08 mov si, 84Ah
E000:1989 E8 F2 52 call F0_Setup_BIOS_Defaults?
E000:198C 0A C0 or al, al
E000:198E 74 05 jz short _next_
E000:1990 80 0E AC 04 20 or ds:byte_0_4AC, 20h
E000:1995 _next_: ; CODE XREF: POST_9S+35
E000:1995 ; POST_9S+43
E000:1995 BF 03 00 mov di, 3
E000:1998 9A 10 50 00 60 call init_Chipset_Reg_again??
E000:199D E8 1E 22 call init_microcode
E000:19A0 E8 9D 2D call nullsub_4
E000:19A3 E8 D6 3F call unknown?
E000:19A6 68 00 E0 push 0E000h
E000:19A9 68 B7 19 push 19B7h
E000:19AC 68 31 EC push 0EC31h
E000:19AF 68 04 50 push 5004h
E000:19B2 EA 30 EC 00 F0 jmp far ptr F000_Vector E000:19B7
; ---------------------------------------------------------------------------
E000:19B7 E8 66 3C call Init_FSB ; SMBus dev 69h init (clock gen chip)
E000:19BA E8 3A 3C call call_init_W3781D_VID_reg
E000:19BD 1F pop ds
E000:19BE assume ds:nothing
E000:19BE F8 clc
E000:19BF C3 retn
E000:19BF POST_9S endp ; sp = -8
As you can see in the code above, this POST_9S is very suspicios. It initializes the FPU (there's an fninit instruction in the called procedure) and the second hint: it calls the microcode initialization routine. The microcode initialization routine is described in [2]. Hence, we proceed further into this procedure until we find (or may not found) our target. I found out that one of the procedure call in this POST_9S is working through the SMBus I/O port. I subsequently name that procedure as Init_FSB and proceed to analyze it. Here's the code:
E000:5620 Init_FSB proc near ; CODE XREF: POST_9S+6C
E000:5620 66 60 pushad
E000:5622 1E push ds
E000:5623 06 push es
E000:5624 9C pushf
E000:5625 0E push cs
E000:5626 1F pop ds
E000:5627 assume ds:_E000h
E000:5627 0E push cs
E000:5628 68 33 56 push 5633h
E000:562B 68 8E 50 push 508Eh ; E_seg_RW_Enable
E000:562E EA 88 61 00 E0 jmp far ptr Fseg_vector E000:5633
; ---------------------------------------------------------------------------
E000:5633 E8 18 00 call nullsub_24
E000:5636 E8 22 00 call Init_FSB_n_Clock_Lines
E000:5639 0E push cs
E000:563A 68 45 56 push 5645h
E000:563D 68 3B 52 push 523Bh ; goto_E_seg_R_Enable
E000:5640 EA 88 61 00 E0 jmp far ptr Fseg_vector E000:5645
; ---------------------------------------------------------------------------
E000:5645 E8 43 01 call call_init_SMBus_dev_69h ; init clock generator
E000:5648 9D popf
E000:5649 07 pop es
E000:564A 1F pop ds
E000:564B assume ds:nothing
E000:564B 66 61 popad
E000:564D C3 retn
E000:564D Init_FSB endp ; sp = -0Ch
The next step is to analyze the SMBus related routine. Note that the base address of the SMBus is found after analyzing the bootblock. It is at I/O port 5000h. This base address is relocatable in the processor address space. That's why preliminary analysis in the bootblock code is needed. Also note that Init_FSB initialize the ds register to point to segment E000h. These informations are needed in later analysis. The SMBus related routine code as follows:
.........
E000:5650 begin_clockgen_init_val
E000:5650 06 db 6
E000:5651 00 db 0
E000:5652 0F db 0Fh
E000:5653 7F db 7Fh
E000:5654 FF db 0FFh
E000:5655 FF db 0FFh
E000:5656 3F db 3Fh
E000:5657 24 db 24h
E000:5657 end_clockgen_init_val
.........
E000:578B call_init_SMBus_dev_69h proc near
E000:578B ; CODE XREF: Init_FSB+25
E000:578B E8 01 00 call init_SMBus_device_69h
E000:578E C3 retn
E000:578E call_init_SMBus_dev_69h endp
E000:578F -- init_SMBus_device_69h --
E000:578F This is a very intriguing procedure.
E000:578F But, I think it initializes the Clock Generator!
E000:578F It's very unfortunate that the Clock Generator datasheet is not available :(
E000:578F ; --------------- S U B R O U T I N E ---------------------------------------
E000:578F init_SMBus_device_69h proc near
E000:578F ; CODE XREF: call_init_SMBus_dev_69h
E000:578F BA 04 50 mov dx, 5004h
E000:5792 B0 D2 mov al, 0D2h ; 'T' ; execute write command to SMBus device 69h
E000:5794 EE out dx, al
E000:5795 E6 EB out 0EBh, al
E000:5797 E6 EB out 0EBh, al
E000:5799 BA 00 50 mov dx, 5000h
E000:579C SMBUS_Host_is_busy: ; CODE XREF: init_SMBus_device_69h+15
E000:579C EC in al, dx
E000:579D E6 EB out 0EBh, al
E000:579F EE out dx, al
E000:57A0 E6 EB out 0EBh, al
E000:57A2 0A C0 or al, al
E000:57A4 75 F6 jnz short SMBUS_Host_is_busy
E000:57A6 BA 02 50 mov dx, 5002h
E000:57A9 EC in al, dx
E000:57AA E6 EB out 0EBh, al
E000:57AC E6 EB out 0EBh, al
E000:57AE BE 50 56 mov si, 5650h
E000:57B1 BA 05 50 mov dx, 5005h
E000:57B4 2E 8A 04 mov al, cs:[si]
E000:57B7 EE out dx, al
E000:57B8 E6 EB out 0EBh, al
E000:57BA E6 EB out 0EBh, al
E000:57BC BE 51 56 mov si, 5651h
E000:57BF BA 07 50 mov dx, 5007h
E000:57C2 next_SMBUS_data: ; CODE XREF: init_SMBus_device_69h+42
E000:57C2 2E 8A 04 mov al, cs:[si]
E000:57C5 EE out dx, al
E000:57C6 E6 EB out 0EBh, al
E000:57C8 E6 EB out 0EBh, al
E000:57CA 83 C6 01 add si, 1
E000:57CD 81 FE 57 56 cmp si, 5657h
E000:57D1 75 EF jnz short next_SMBUS_data
E000:57D3 BA 02 50 mov dx, 5002h
E000:57D6 B0 54 mov al, 54h ; 'T' ; start SMBUS block write
E000:57D8 EE out dx, al
E000:57D9 E6 EB out 0EBh, al
E000:57DB E6 EB out 0EBh, al
E000:57DD 33 C9 xor cx, cx
E000:57DF BA 00 50 mov dx, 5000h
E000:57E2 host_not_done_yet: ; CODE XREF: init_SMBus_device_69h+5A
E000:57E2 EC in al, dx
E000:57E3 E6 EB out 0EBh, al
E000:57E5 A8 02 test al, 2
E000:57E7 75 02 jnz short done E000:57E9 E2 F7 loop host_not_done_yet
E000:57EB done: ; CODE XREF: init_SMBus_device_69h+58
E000:57EB C3 retn
E000:57EB init_SMBus_device_69h endp
As you can see in the code above, there's a routine that carry-out a "block-write" into the device that is attached to the SMBus, the device number is 69h. The block of data that's written to the SMBus is located at E000:5651h-E000:5657h. Since this procedure is located near the CPU initialization routine, our intuition told us that the corresponding device must be a clock generator chip. A comparison to other similar chip's datasheet, i.e. clock generator datasheet confirm that. I used winbond's clock generator data sheet (W83194R-37) for that. In the datasheet, it says it can generate clock for several PCI devices, an AGP devices, some SDRAM modules and some CPUs. It's also mentioned in the datasheet that the initialization is carried-out by using the SMBus to access the configuration register of the chip. With the init_SMBus_device_69h procedure at hand, I try to find another procedure that is called by Init_FSB to modify the block of data that is written into the SMBus device 69h. I found the call to the procedure in Init_FSB and name it as Init_FSB_n_Clock_Lines. The procedure as follows:
.........
E000:5650 begin_clockgen_init_val
E000:5650 06 db 6
E000:5651 00 db 0
E000:5652 0F db 0Fh
E000:5653 7F db 7Fh
E000:5654 FF db 0FFh
E000:5655 FF db 0FFh
E000:5656 3F db 3Fh
E000:5657 24 db 24h
E000:5657 end_clockgen_init_val
.........
E000:565B Init_FSB_n_Clock_Lines proc near ; CODE XREF: Init_FSB+16
E000:565B BE 5A 15 mov si, 155Ah
E000:565E E8 1D 16 call F0_Setup_BIOS_Defaults? ; DRAM type?
E000:5661 0A C0 or al, al
E000:5663 0F 85 85 00 jnz next
E000:5667 E8 78 42 call XGROUP_Set_RAM_type_2_SDRAM
E000:566A BE 54 56 mov si, 5654h ; SMBUS cmd index, hmmm what is it :?
E000:566D A8 03 test al, 3
E000:566F 75 04 jnz short bank01_populated
E000:5671 2E 80 24 FE and byte ptr cs:[si], 0FEh ; disable clock-line for bank-0&1 in ClockGen-Chip
E000:5675 bank01_populated: ; CODE XREF: Init_FSB_n_Clock_Lines+14
E000:5675 A8 0C test al, 0Ch
E000:5677 75 04 jnz short bank23_populated
E000:5679 2E 80 24 FD and byte ptr cs:[si], 0FDh ; disable clock-line for bank-2&3 in ClockGen-Chip
E000:567D bank23_populated: ; CODE XREF: Init_FSB_n_Clock_Lines+1C
E000:567D A8 30 test al, 30h
E000:567F 75 04 jnz short bank45_populated
E000:5681 2E 80 24 FF and byte ptr cs:[si], 0FFh
E000:5685 bank45_populated: ; CODE XREF: Init_FSB_n_Clock_Lines+24
E000:5685 BE 53 56 mov si, 5653h
E000:5688 B9 04 78 mov cx, 7804h ; PCI bus0,devFh,func0,reg4h -- init PCI clock line
E000:568B 56 push si
E000:568C 0E push cs
E000:568D 68 98 56 push 5698h
E000:5690 68 AA 51 push 51AAh ; PCI_Bus0_Read_cfg_byte
E000:5693 EA 88 61 00 E0 jmp far ptr Fseg_vector E000:5698
; ---------------------------------------------------------------------------
E000:5698 5E pop si
E000:5699 3C FF cmp al, 0FFh ; is read failed/device not exist?
E000:569B 75 04 jnz short PCI_Bus_0_Dev_Fh_exist
E000:569D 2E 80 24 BF and byte ptr cs:[si], 0BFh ; disable PCI clock output
E000:56A1 PCI_Bus_0_Dev_Fh_exist: ; CODE XREF: Init_FSB_n_Clock_Lines+40
E000:56A1 B9 04 80 mov cx, 8004h ; PCI bus0,dev10h,func0,reg4h -- init PCI clock line
E000:56A4 56 push si
E000:56A5 0E push cs
E000:56A6 68 B1 56 push 56B1h
E000:56A9 68 AA 51 push 51AAh ; PCI_Bus0_Read_cfg_byte
E000:56AC EA 88 61 00 E0 jmp far ptr Fseg_vector E000:56B1
; ---------------------------------------------------------------------------
E000:56B1 5E pop si
E000:56B2 3C FF cmp al, 0FFh ; is read failed/device not exist?
E000:56B4 75 04 jnz short PCI_Bus_0_Dev_10h_exist
E000:56B6 2E 80 24 FE and byte ptr cs:[si], 0FEh ; disable PCI clock output
E000:56BA PCI_Bus_0_Dev_10h_exist: ; CODE XREF: Init_FSB_n_Clock_Lines+59
E000:56BA B9 04 90 mov cx, 9004h ; PCI bus0,dev12h,func0,reg4h -- init PCI clock line
E000:56BD 56 push si
E000:56BE 0E push cs
E000:56BF 68 CA 56 push 56CAh
E000:56C2 68 AA 51 push 51AAh ; PCI_Bus0_Read_cfg_byte
E000:56C5 EA 88 61 00 E0 jmp far ptr Fseg_vector E000:56CA
; ---------------------------------------------------------------------------
E000:56CA 5E pop si
E000:56CB 3C FF cmp al, 0FFh ; is read failed/device not exist?
E000:56CD 75 04 jnz short PCI_Bus_0_Dev_12h_exist
E000:56CF 2E 80 24 EF and byte ptr cs:[si], 0EFh ; disable PCI clock output
E000:56D3 PCI_Bus_0_Dev_12h_exist: ; CODE XREF: Init_FSB_n_Clock_Lines+72
E000:56D3 B9 04 98 mov cx, 9804h ; PCI bus0,dev13h,func0,reg4h -- init PCI clock line
E000:56D6 56 push si
E000:56D7 0E push cs
E000:56D8 68 E3 56 push 56E3h
E000:56DB 68 AA 51 push 51AAh ; PCI_Bus0_Read_cfg_byte
E000:56DE EA 88 61 00 E0 jmp far ptr Fseg_vector
E000:56E3 ; ---------------------------------------------------------------------------
E000:56E3 5E pop si
E000:56E4 3C FF cmp al, 0FFh ; is read failed/device not exist?
E000:56E6 75 04 jnz short next
E000:56E8 2E 80 24 F7 and byte ptr cs:[si], 0F7h ; disable PCI clock output
E000:56EC next: ; CODE XREF: Init_FSB_n_Clock_Lines+8
E000:56EC ; Init_FSB_n_Clock_Lines+8B
E000:56EC B0 A0 mov al, 0A0h ; 'a'
E000:56EE E8 17 43 call F0_Read_Port_73h
E000:56F1 3C 55 cmp al, 55h ; 'U'
E000:56F3 74 7A jz short setup_DRAM_clock?
E000:56F5 B0 A1 mov al, 0A1h ; 'a'
E000:56F7 E8 0E 43 call F0_Read_Port_73h
E000:56FA 24 F0 and al, 0F0h
E000:56FC BE 51 56 mov si, 5651h
E000:56FF 2E 80 0C 08 or byte ptr cs:[si], 8
E000:5703 50 push ax
E000:5704 B9 68 00 mov cx, 68h ; 'h' ; DRAM Control
E000:5707 0E push cs
E000:5708 68 13 57 push 5713h
E000:570B 68 0B F7 push 0F70Bh ; Read_PCI_Bus0_Byte
E000:570E EA 88 61 00 E0 jmp far ptr Fseg_vector
E000:5713 ; ---------------------------------------------------------------------------
E000:5713 A8 02 test al, 2 ; FSB = 133Mhz/Reserved?
E000:5715 74 13 jz short FSB_66MHz_or_100MHz
E000:5717 58 pop ax
E000:5718 8A D8 mov bl, al
E000:571A 24 C0 and al, 0C0h
E000:571C 3C C0 cmp al, 0C0h ; 'L'
E000:571E 8A C3 mov al, bl
E000:5720 74 3C jz short FSB_init_done
E000:5722 B0 F0 mov al, 0F0h ; '?'
E000:5724 83 4E 38 40 or word ptr [bp+38h], 40h
E000:5728 EB 34 jmp short FSB_init_done
E000:572A ; ---------------------------------------------------------------------------
E000:572A FSB_66MHz_or_100MHz: ; CODE XREF: Init_FSB_n_Clock_Lines+BA
E000:572A A8 01 test al, 1
E000:572C 74 1B jz short FSB_66MHz
E000:572E 58 pop ax
E000:572F 8A D8 mov bl, al
E000:5731 24 C0 and al, 0C0h
E000:5733 3C 00 cmp al, 0
E000:5735 74 04 jz short loc_E000_573B
E000:5737 8A C3 mov al, bl
E000:5739 75 23 jnz short FSB_init_done
E000:573B loc_E000_573B: ; CODE XREF: Init_FSB_n_Clock_Lines+DA
E000:573B 8A C3 mov al, bl
E000:573D 3C 00 cmp al, 0
E000:573F 74 1D jz short FSB_init_done
E000:5741 loc_E000_5741:
E000:5741 B0 70 mov al, 70h ; 'p'
E000:5743 83 4E 38 40 or word ptr [bp+38h], 40h
E000:5747 EB 15 jmp short FSB_init_done
E000:5749 ; ---------------------------------------------------------------------------
E000:5749 FSB_66MHz: ; CODE XREF: Init_FSB_n_Clock_Lines+D1
000:5749 58 pop ax
E000:574A 8A D8 mov bl, al
E000:574C 3C 00 cmp al, 0
E000:574E 74 08 jz short loc_E000_5758
E000:5750 24 C0 and al, 0C0h
E000:5752 3C 00 cmp al, 0
E000:5754 8A C3 mov al, bl
E000:5756 74 06 jz short FSB_init_done
E000:5758 loc_E000_5758: ; CODE XREF: Init_FSB_n_Clock_Lines+F3
E000:5758 B0 30 mov al, 30h ; '0'
E000:575A 83 4E 38 40 or word ptr [bp+38h], 40h
E000:575E FSB_init_done: ; CODE XREF: Init_FSB_n_Clock_Lines+C5
E000:575E ; Init_FSB_n_Clock_Lines+CD ...
E000:575E 50 push ax
E000:575F 24 80 and al, 80h
E000:5761 A8 80 test al, 80h
E000:5763 58 pop ax
E000:5764 74 04 jz short loc_E000_576A
E000:5766 2E 80 0C 04 or byte ptr cs:[si], 4
E000:576A loc_E000_576A: ; CODE XREF: Init_FSB_n_Clock_Lines+109
E000:576A 24 7F and al, 7Fh
E000:576C 2E 08 04 or cs:[si], al
E000:576F setup_DRAM_clock?: ; CODE XREF: Init_FSB_n_Clock_Lines+98
E000:576F BE 73 15 mov si, 1573h
E000:5772 E8 09 15 call F0_Setup_BIOS_Defaults?
E000:5775 0A C0 or al, al
E000:5777 74 11 jz short exit
E000:5779 BE 51 56 mov si, 5651h
E000:577C 2E 80 0C 02 or byte ptr cs:[si], 2
E000:5780 FE C8 dec al
E000:5782 A8 01 test al, 1
E000:5784 74 04 jz short exit
E000:5786 2E 80 0C 80 or byte ptr cs:[si], 80h
E000:578A exit: ; CODE XREF: Init_FSB_n_Clock_Lines+11C
E000:578A ; Init_FSB_n_Clock_Lines+129
E000:578A C3 retn
E000:578A Init_FSB_n_Clock_Lines endp ; sp = -0Eh
After reading the procedure, some more hints shows up, such as checking the availability of certain PCI device, followed by modifcation of the SMBus command (block of data that is later sent through the SMBus). I suspect that this routine modifies the output of the clock generator to certain PCI clock lines. The only way to confirm this is by modifying the suspected routine and observe the effect of the modification. Thus, I carried out a small experiment. I modify the code so that the PCI clock-line to device in PCI bus 0 device number 13h will be disabled, as follows:
E000:565B Init_FSB_n_Clock_Lines proc near ......... E000:56D3 PCI_Bus_0_Dev_12h_exist: ; CODE XREF: seg000:56CD E000:56D3 90 nop
E000:56D4 90 nop
E000:56D5 90 nop
E000:56D6 90 nop
E000:56D7 90 nop
E000:56D8 90 nop
E000:56D9 90 nop
E000:56DA 90 nop
E000:56DB 90 nop
E000:56DC 90 nop
E000:56DD 90 nop
E000:56DE 90 nop
E000:56DF 90 nop
E000:56E0 90 nop
E000:56E1 90 nop
E000:56E2 90 nop
E000:56E3 90 nop
E000:56E4 90 nop
E000:56E5 90 nop
E000:56E6 90 nop
E000:56E7 90 nop
E000:56E8 2E 80 24 F7 and byte ptr cs:[si], 0F7h ; disable PCI clock output at PCI Bus 0 Dev 13h
E000:56EC
E000:56EC next: ; CODE XREF: seg000:5663
E000:56EC B0 A0 mov al, 0A0h ; 'a'
.........
E000:578A Init_FSB_n_Clock_Lines endp
With the original BIOS, the device that resides at PCI bus 0 device 13h is a Realtek 8139 LAN card. This card is attached to the PCI expansion slot of the Iwill VD133 mainboard. Thus, the modification above will disable the clock-line for this PCI slot.
After flashing the modified BIOS (with clock output to PCI bus 0 dev 13h disabled), I checked the existence of the device in windows and during power-up (in the BIOS screen for PCI devices). The network card is not shown, eventhough the card is installed. Voila', our guess is right! The code is indeed controlling the clock generator setting for PCI bus 0 Device 13h.
However, reflashing the original BIOS again wouldn't bring back the PCI slot to active immediately. I have to shutdown the system totally and starting it back to make the PCI slot active again. Simple system restart is not enough to carry out a clock-generator re-initialization.
As before, if you want to try this modification yourself, patch the highlighted instructions by using hexeditor as shown above. But again, remember that proceed at your own risk.
Anyway, you might expect me to provide you with a signature for this clock-generator initialization routine. Unfortunately, I don't. Because I think that after going through the article this far you can figure it out yourself ;-).
OK, the modification story ended-up here. Now, we know how to deal even with the most obscure kind of modification with incomplete datasheet at hand (^__^).
4. Generic System-BIOS Patching Ninjutsu
I've tried to apply the trick described in section 3 to Modbin6 version 2.01 for Award BIOS version 6 binary. But, I haven't try the modified BIOS yet. The preliminary test shows that Modbin6 generates temporary ORIGINAL.BIN, MLSTRING.BIN and XGROUP.BIN files. Nevertheless, further tests are needed to find-out its properties.
From the experiments that I've carried-out, it's clear that possibly, most of the sytem-BIOS altering programs, such as modbin , generates temporary files during their execution. Thus, we can use that opportunity to patch the binary, provided that we've known their structure in advance. In the mean time, we can conclude that the general system-BIOS patching steps are as follows:
Open the BIOS binary to be patched with the system-BIOS "altering" program.
Open the temporary decompressed system BIOS component that is generated by step a in hexeditor and subsequently patch it with the hexeditor. At this point, one can also copy the decompressed system BIOS to another directory to be examined later with disassembler.
Save the changes that are made and close the system-BIOS "altering" program.
The principles above supposedly work for all kind of BIOS. Hence, it's a matter of having the right utility at hand.
Have a nice day (^__^).
5. References
W83194R-37/-58 datasheet (Clock Synthesizer for VIA chipset). Winbond Electronics Corp. 1998.
Copyright © Darmawan M S a.k.a Pinczakko