+ Reply to Thread
Results 1 to 8 of 8

Thread: Decode Edit NVRAM Phoenix plus Setup Menu

  1. Join Date
    Sep 2009
    Posts
    84
    Rep Power
    21

    Decode Edit NVRAM Phoenix plus Setup Menu

    Decoding the NVRAM from the Phoenix BIOSROM image/ Mod your Phoenix Setup menu.

    First this is just a long note on where the locations are and some decoding for learning about the phoenix bios. This is not a step by step guide on modding your bios for adding features. This info will point you in the right way but bottom line messing with the bios can brick your machine. Don't go messing if you have no idea what building or modding is. This is still a work in progress and might be missing some ref points from my scribble notes... Trying to collect and format these notes. Note all the numbers that I use in reference are in Hex format unless specifically stated other wise.

    The NVRAM can be decoded by two ways. One is directly from the stored memory location of the PC you are working on. The other is by finding the token table from the BIOS image. In memory the token table is found in the F000:0000 range of memory.. You can use a tool like symcmos or code something yourself to search and dump the tables. DOS debug will work fine. Search for the string BCPNV for the memory locations. This is the location the phoenix dispatch messenger will check for. symcmos searches for the the $PDM in memory. Decomp your BIOS image and search for $PDM, romexec0.

    PDM: Search in memory for '$PDM'.
    Code:
    F000:5FB0  24 50 44 4D 01 0B 46 3E-7B 00 F0 00 00 00 00 00   $PDM..F>{.......
    This has a 8 bit checksum = 00 check. When adding up the bytes it should end in 00. The 0B, 0B is total length. The next area is the far jump location in memory for the $PDM area. In my case this was E649:177D.


    PDM_1: The PDM controls access to the NVRAM token table. For example the VT bit, Virtual Technology Processing option is disabled in many BIOS. The OEM vendor has chosen to disable this. If you debug your BIOS you will find the MSR call to verify if this bit is enabled or disabled. The PDM locations will be called. Here is what my PDM table looks like in IDA. 1761 through 177B holds the jump offset table. The calls to these locations are below the 117D, first call 1799. It will be possible to enable and disable some options in your BIOS directly from the OS using the calls in the BIOS. symcmos can import some NVRAM settings, often cleared on power cycle though. This is where hacking the NVRAM table in your BIOS ROM will come in handy as some bytes are locked from writing by MSR.
    Cut some of the code to shorten it.
    Code:
    E649:1761 off_E7BF1       dw offset sub_E7C3A     ; DATA XREF: seg000:1799
    E649:1763                 dw offset sub_E7C56
    E649:1765                 dw offset sub_E7C5D
    E649:1767                 dw offset sub_E7C64
    E649:1769                 dw offset sub_E7C7D
    E649:176B                 dw offset sub_E7D2F
    E649:176D                 dw offset sub_E7D3C
    E649:176F                 dw offset sub_E7D49
    E649:1771                 dw offset sub_E7D56
    E649:1773                 dw offset sub_E7C90
    E649:1775                 dw offset sub_E7D63
    E649:1777                 dw offset sub_E7CA8
    E649:1779                 dw offset sub_E7CC6
    E649:177B                 dw offset sub_E7C43
    E649:177D ; ---------------------------------------------------------------------------
    E649:177D
    E649:177D loc_E7C0D:
    E649:177D                 push    bp
    E649:177E                 mov     bp, sp
    E649:1780                 push    gs
    E649:1782                 push    ds
    E649:1783                 push    es
    E649:1784                 pushad                  ; Push all General Registers (use32)
    E649:1786                 push    0F000h
    E649:1789                 pop     gs
    E649:178B                 assume gs:nothing
    E649:178B                 mov     ax, 0FFFEh
    E649:178E                 mov     di, [bp+6]
    E649:1791                 cmp     di, 0Eh         ; Compare Two Operands
    E649:1795                 jnb     short loc_E7C2E ; Jump if Not Below (CF=0)
    E649:1797                 shl     di, 1           ; Shift Logical Left
    E649:1799                 call    cs:off_E7BF1[di] ; Indirect Call Near Procedure
    E649:179E
    E649:179E loc_E7C2E:                              ; CODE XREF: seg000:1795j
    E649:179E                 mov     gs, ax
    E649:17A0                 assume gs:nothing
    E649:17A0                 popad                   ; Pop all General Registers (use32)
    E649:17A2                 mov     ax, gs
    E649:17A4                 pop     es
    E649:17A5                 pop     ds
    E649:17A6                 pop     gs
    E649:17A8                 assume gs:nothing
    E649:17A8                 pop     bp
    E649:17A9                 retf                    ; Return Far from Procedure
    E649:17AA
    E649:17AA ; =============== S U B R O U T I N E =======================================
    E649:17AA
    E649:17AA
    E649:17AA sub_E7C3A       proc near               ; CODE XREF: seg000:1799p
    E649:17AA                                         ; DATA XREF: seg000:off_E7BF1o
    E649:17AA                 mov     ax, [bp+8]
    E649:17AD                 call    sub_F3E3F       ; Call Procedure
    E649:17B2                 retn                    ; Return Near from Procedure
    E649:17B2 sub_E7C3A       endp
    E649:17B2
    E649:17B3
    E649:17B3 ; =============== S U B R O U T I N E =======================================
    E649:17B3
    E649:17B3
    E649:17B3 sub_E7C43       proc near               ; CODE XREF: seg000:1799p
    E649:17B3                                         ; DATA XREF: seg000:177Bo
    E649:17B3                 mov     ax, [bp+8]
    E649:17B6                 call    sub_E7CEE       ; Call Procedure
    E649:17B9                 jb      short locret_E7C55 ; Jump if Below (CF=1)
    E649:17BB                 movzx   si, byte ptr [si+0Eh] ; Move with Zero-Extend
    E649:17BF                 call    sub_E7D25       ; Call Procedure
    E649:17C2                 mov     ax, 0
    E649:17C5
    E649:17C5 locret_E7C55:                           ; CODE XREF: sub_E7C43+6j
    E649:17C5                 retn                    ; Return Near from Procedure
    E649:17C5 sub_E7C43       endp
    E649:17C5
    E649:17C6
    E649:17C6 ; =============== S U B R O U T I N E =======================================
    E649:17C6
    E649:17C6
    E649:17C6 sub_E7C56       proc near               ; CODE XREF: seg000:1799p
    E649:17C6                                         ; DATA XREF: seg000:1763o
    E649:17C6                 mov     bx, 2
    E649:17C9                 call    sub_E7C6B       ; Call Procedure
    E649:17CC                 retn                    ; Return Near from Procedure
    E649:17CC sub_E7C56       endp
    E649:17CC
    E649:17CD
    E649:17CD ; =============== S U B R O U T I N E =======================================
    E649:17CD
    E649:17CD
    E649:17CD sub_E7C5D       proc near               ; CODE XREF: seg000:1799p
    E649:17CD                                         ; DATA XREF: seg000:1765o
    E649:17CD                 mov     bx, 0Ah
    E649:17D0                 call    sub_E7C6B       ; Call Procedure
    E649:17D3                 retn                    ; Return Near from Procedure
    E649:17D3 sub_E7C5D       endp
    E649:17D3
    E649:17D4
    E649:17D4 ; =============== S U B R O U T I N E =======================================
    E649:17D4
    E649:17D4
    E649:17D4 sub_E7C64       proc near               ; CODE XREF: seg000:1799p
    E649:17D4                                         ; DATA XREF: seg000:1767o
    E649:17D4                 mov     bx, 6
    E649:17D7                 call    sub_E7C6B       ; Call Procedure
    E649:17DA                 retn                    ; Return Near from Procedure
    E649:17DA sub_E7C64       endp
    E649:17DA
    E649:17DB
    ....
    E649:18E0 ; ---------------------------------------------------------------------------
    E649:18E0                 call    sub_E7CEE       ; Call Procedure
    E649:18E3                 retf                    ; Return Far from Procedure
    E649:18E4 ; ---------------------------------------------------------------------------
    E649:18E4                 call    sub_E7D1A       ; Call Procedure
    E649:18E7                 retf                    ; Return Far from Procedure
    E649:18E8 ; ---------------------------------------------------------------------------
    E649:18E8                 call    sub_E7CFC       ; Call Procedure
    E649:18EB                 retf                    ; Return Far from Procedure
    E649:18EC ; ---------------------------------------------------------------------------
    E649:18EC                 call    sub_E7D0A       ; Call Procedure
    E649:18EF                 retf                    ; Return Far from Procedure
    E649:18F0 ; ---------------------------------------------------------------------------
    E649:18F0                 retn                    ; Return Near from Procedure
    E649:18F0 ; ---------------------------------------------------------------------------
    PDM_2:

    In the few roms I have looked at the $PDM has been found in the ROMEXEC0.ROM file. The entire BCP table structure can be found below the $PDM entry. The PDM call locations for me is in the BIOSCOD02.ROM file. I loaded up my ROM in IDA and adjusted it to get the correct offsets. To get your actual offsets will require forcing the memory locations when loading in IDA. You can also use a NDISASM to decompile your rom images but this is not always accurate because you don't know what the start location of the CODE section is. The rom has no structure like an exe does. You need to load up in 16 bit mode. example of using NDISASM.
    ndisasm -a -p intel -b 16 input.rom > output.dasm


    NVRAM: NVRAM holds the entire token table assigned by Standard Defaults Table and Manufacture Defaults Table. Look for the BCPNV in memory or the ROMEXEC file. This is similar pattern with many of the table structures. See below romexec and memory. The 1F is the length from BCPNV to end. The bytes that follow are the locations stored in endian format. 32,66 is memory location F000:6632. If you use dos debug. cmd prompt. type in DEBUG. screen should have blinking cursor -. d F000:6632 <- use your memory location not mine. enter q to quit

    Code:
    romexec 51C3:
    h: 10 42 43 50 4E 56 20 00 01 1F 00 00 32 66 32 66  .BCPNV .....2f2f 
    h: 00 00 4A 46 FF FF B8 69 12 70 B0 66 30 68 2C 3B  ..JF...i.p.f0h,; 
    
    memory
    F000:6630        42 43 50 4E 56 20-00 01 1F 00 00 32 66 32     BCPNV .....2f2
    F000:6640  66 00 00 4A 46 FF FF B8-69 12 70 B0 66 30 68 2C   f..JF...i.p.f0h,
    6632 is the CMOS Default Table Offset, the second 6632 is the size.
    464A is the CMOS Checksum
    FFFF is CRC Mask
    69B8 offset starts the Token Table.
    7012 offset ends the Token Table.
    66B0 offset starts the Standard Defaults for NVRAM
    6830 offset starts the Manufacturing Defaults for NVRAM
    3B2C offset starts Media for NVRAM.
    Using PBE, you can see the same results from the BCP menu.

    If you use dos DEBUG for those locations offset locations you will see your tables in memory. d F000:69B8 will show the Start of Token table.

    To find the physical locations in the file just do the math to find the offset. Using 6632 as the ref point. In my romexec, 6632 is the same as 51C3. The offset for the token table start is 69B8. 69B8 - 6632 = 386. Add that to physical location. 51C3 + 386 = 5549.

    TOKEN TABLE:
    The toke table is a table by 3's. Every 3 bytes is a new table. The location matches the offset of the file location. So it makes a lot easier to just copy the entire table to a new file. 01 8F 00 is the first token, 0. To save for size, I'm not going to cut n paste the entire table. Only going to show the first 3F bytes of the Token table. My token table is 659h in size.
    Code:
    5540h: 00 24 4E 56 54 01 01 12 70 01 8F 00 01 23 01 41  .$NVT...p....#.A 
    		
    		0 1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
    0000h: 01 8F 00 01 23 01 41 A7 01 51 33 03 51 34 03 51  ....#.A..Q3.Q4.Q 
    0010h: 35 03 51 36 03 51 37 03 51 38 03 51 39 03 51 3A  5.Q6.Q7.Q8.Q9.Q: 
    0020h: 03 51 3B 03 51 3C 03 51 3D 03 D0 E4 30 50 86 02  .Q;.Q<.Q=...0P.. 
    0030h: D0 E0 30 08 00 90 00 50 70 00 58 00 00 59 60 00  ..0....Pp.X..Y`.
    So Token 0C is [51 34 03] [x1 xx xx], the 1 in 51 means Media 1, [xx 34 x3] the token start location or bit start is 334, [xx xx 0x] the 0 is the width bit. Add 1 to what ever this number is. So my token 0C starts at 334 and is 1 bit width with possibly of max value 1, 1 or 0. Do this for every 3 bytes. The next token would be 0F. 51 35 03 Token starts at 335, width is 1, media location 1... Tokens are stored in memory in by the starting sort order. So for these two, the entries are together in memory. bit 334 and bit 335. If you were sort your final table, sort by media store then start location. The location will follow by width plus byte. So if a token is 4 bits width, the next token start will be 4 bits away. ex if token 37 was 4 bits wide starting at 336, the next available location would be 33A. No token table would start at 338 in that media store.

    TOKENS:
    From the BCPNV table go to the Standard Defaults Table offset. The ending byte is the byte before the start of the MFG table. Mine is 17F bytes length. Copy and paste both tables into new files. This helps with the locations. Below is my Std table and Media Store. Media store is going to make 8 locations. 0 - 7 Grab the first F bytes.
    Code:
    Std Default Table
    0000h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................ 
    0010h: 40 46 00 C8 01 00 00 00 00 00 00 60 02 22 B8 14  @F.........`.".. 
    0020h: 42 C0 11 A9 0D 39 F8 04 82 05 84 60 20 8A 00 00  B....9.....` ... 
    0030h: 00 00 20 00 00 02 00 00 00 00 00 00 00 00 00 00  .. ............. 
    0040h: 00 00 00 00 33 00 00 00 00 40 F0 FF 01 FC 01 C0  ....3....@...... 
    0050h: 84 00 00 00 00 00 00 00 68 04 E0 FE FF 01 00 02  ........h....... 
    0060h: 11 30 11 11 11 11 00 0F 00 00 00 00 0F 40 F4 8B  .0...........@.. 
    0070h: 00 00 64 EF 48 84 00 90 04 E0 90 86 00 00 00 80  ..d.H........... 
    0080h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................ 
    0090h: 00 80 00 00 00 01 00 00 00 00 00 00 00 00 00 00  ................ 
    00A0h: 00 00 00 00 00 00 00 00 00 00 64 03 D0 95 BD 0F  ..........d..... 
    00B0h: 00 01 00 00 00 00 00 40 00 00 00 00 00 00 00 00  .......@........ 
    00C0h: 00 00 00 00 00 00 00 02 00 00 00 10 00 02 40 40  ..............@@ 
    00D0h: 18 00 00 E1 E4 00 00 00 10 00 40 00 00 01 00 04  ..........@..... 
    00E0h: 00 10 00 40 00 00 39 00 60 BC 1F 00 00 00 00 00  ...@..9.`....... 
    00F0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5A  ...............Z 
    0100h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................ 
    0110h: 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00  ................ 
    0120h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................ 
    0130h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................ 
    0140h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................ 
    0150h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................ 
    0160h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................ 
    0170h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................ 
    
    Media Table
    0000h: 00 00 00 04 00 08 A8 08 A8 08 B0 08 B0 08 B0 08  ................
    Media Table broken down.
    Media 0 = 0000
    Media 1 = 0400
    Media 2 = 0800
    Media 3 = 08A8
    Media 4 = 08A8
    Media 5 to 7 = 08B0

    The media table represents the max amount bits can be stored in that table. Media 0 starts 00. Media 1 starts at 400h so 3FFh is the last bit of media 0. Converting the entire range into binary would result in 3FF entries of 1's 0's. So we have two sets of bits 3FFh wide. Media 2 starts 800, 3 08A8 etc... The table needs to broken down into what holds what media location in bytes. So 400h bits can be represented by our bytes table by dividing it into 8 bits. 400h / 8h = 80h Media 1 starts at 80h. So 0 - 7F is Media 0, 80h - FFh is Media 1. 100h starts Media 2 but is 15 bytes len because Media 3 starts 08A8. 115h starts Media 3 and 4.

    Token Value:
    Use the locations of the table above to figure out what the value of the token is. In the example above we used 334 Media 1. 334 divide by 8, be sure in hex. 334 / 8 = 66 not using remainders in Hex. 66 * 8 = 330. So 66h is the location in media 1. Media 1 starts at 80h + 66h = E6h Token at E6 is 39, use the table above. Break 39 down into binary. 00111001 Take 66 and multiply by 8 to get where the bits start is. 66h * 8h = 330h So the start location of our binary number for 39h is bit 330. Working in reverse order here.
    Code:
    	0 | 0 | 1 | 1 | 1 | 0 | 0 | 1 
    	337 336 335 334 333 332 331 330
    Bit 334 is enabled Change bit 334 to 0 and convert the binary back to hex. 00101001 is 29h So E6 can hold 8 bits of info. If 334 and 333 were both disabled, E6 will become 21h.

    Token Ref:
    That is break down of the token table. Now to find out what token represents what value. IE find out what token 0C, at start point 334, in media 1, is represented at location E6 with the value of 39. The easiest way is to use SYMCMOS tool from Phoenix. Take this tool and your strings.rom and template.rom and you have a complete map of your system. This also allows you to map out your BIOS Setup to enable options in your BIOS. It's not the only way, you can do it manually or parse the file with your own code to dump it.

    SYMCMOS:
    First you need to run this tool from a boot disk. Running from inside windows will cause problems with memory locations and access rights. freedos is supported by this tool.
    I am going straight into the functions needed to get a dump but it does more than this.
    rename templat0.rom to nodes.rom, rename strings0.rom to strings.rom
    Run symcmos -v2 -C This will combine the two files in regions for symcmos to map out. It creates a file called combine.rom
    run symcmos -v2 -Fcombine.rom -Ssymbol.txt >symbol_.txt The ">sysmbol_.txt" is going dump/pipe the screen output into a text file. Run it without the pipe to see it in action. It displays a bunch of info not included from the dump file. There are no spaces after the -S -F and file name.
    Now run it with -L for a list file that can be edited and imported.
    symcmos -v2 -Lliteral.txt Output the pipe again to a text file to keep a list of the skipped. The -L dump you can import a new bit setting for any token if it is writable. Read more in the documents about using symcmos.
    Note different versions of symcmos display more info than others in the output screen.

    Now if your PC was the same as mine you would get a print out and see that 334 is really AHCI in the Advanced menu of the BIOS:
    Code:
    	Advanced
          Internal_Device_Configurations
             _AHCI_Configuration:
                ( token 0xC  start 0x334  width 0x1 )
                ( maximum 0x1  default 0x1  PICK_FIELD )
                   =   [0]  Disabled
                   =*  [1]  Enabled
    			   
    	writeOptions(00h,14h,0808h,0806h,5e6ah,5eb3h,) ... 
        ( token 0xC  start 0x334  width 0x1 ) max 0x1, default 0x1
    Now because this symcmos read the settings directly from the NVRAM location we get our current settings that matches the bios rom file we are using. If you use a bios file not for the PC you are running it on, it will fail. For this you need to patch the tool, code your own or modify the symcmos tool to read physical memory location or patch the segment and manually load up the tokens in memory to a matching segment. You could parse this info out with a perl script, just need to know how the setup is created...

    Setup:
    The setup table is controlled by the templat0.rom and strings0.rom files. You will need to copy the bytes of the strings0.rom file to a new file and delete the header so the offsets match up.
    Code:
    0000h: 53 54 52 50 41 43 4B 2D 42 49 4F 53 00 00 00 00  STRPACK-BIOS.... 
    0010h: 00 00 00 00 00 00 00 00 02 00 02 00 F9 8D 52 03  ..............R. 
    0020h: 75 73 1A 00 D3 64 E0 08 EF 08 19 09 39 09 84 09  us...d......9...
    All the bytes up to F98D are header. Remove. the 02 00 02 00 means there are two languages in this file. F98D is the length of the first language, after 8DF9: starts JP (Japan) our section is EN (US). Yours may have more or only 1. This should be the same file as OLD.RLS from unpacking the bios.rom in Phoenix Bios Editor. PBE divides them up by OLD1, OLD2, OLD3.RLS

    So the file I am working with will starts off like this.
    Code:
    0000h: F9 8D 52 03 75 73 1A 00 D3 64 E0 08 EF 08 19 09  ..R.us...d...... 
    0010h: 39 09 84 09 AD 09 BC 09 E5 09 00 0A 0A 0A 16 0A  9............... 
    0020h: 25 0A 34 0A 43 0A 52 0A 61 0A 70 0A 7F 0A 8E 0A  %.4.C.R.a.p.... 
    0030h: 9D 0A AA 0A B1 0A B6 0A C8 0A D3 0A EB 0A 10 0B  ................ 
    0040h: 25 0B 2A 0B 2F 0B 34 0B 39 0B 3E 0B 43 0B 48 0B  %.*./.4.9.>.C.H. 
    0050h: 4D 0B 52 0B 57 0B 5C 0B 61 0B 66 0B 6B 0B 70 0B  M.R.W.\.a.f.k.p. 
    0060h: 75 0B 7A 0B 7F 0B 84 0B 89 0B 8E 0B 93 0B 98 0B  u.z............ 
    0070h: 9D 0B A2 0B A7 0B AC 0B B1 0B B6 0B BB 0B C0 0B  ................
    This file is a map in table format that is linked to the offsets from the template file (nodes). The NODES are mapped in a continous jumps until it reaches 0000. 0000 is the end of that one node. When the node is terminated it jumps back to the last jump it came from.

    Below is a clip from the strings rom. At location 0674: 09 67 This points to 6709: Byte 4D for Main, the 00 byte terminates after Main.
    Code:
    0670h: F5 66 01 67 09 67 0E 67 1D 67 3A 67 50 67 7D 67  .f.g.g.g.g:gPg}g 
    6700h: 00 4D 61 67 65 6E 74 61 00 4D 61 69 6E 00 4D 61  .Magenta.Main.Ma
    In the nodes file (templat0.rom) an offset calls to location 0674 in the format of 74 06.
    Code:
    11ADh: 10 0A 74 06 00 00 6B 39 98 39                    ..t...k9.9
    Location at 11AD: which is also linked as AD 11 in the node table.
    These bytes I am still working on a few items. What I have worked out is the first byte determines the type. The 2nd byte is the total length starting from first byte. The 3rd and 4th byte are the 1st table reference in strings.rom. The 5th and 6th byte are the 2nd table reference in strings.rom. (item and description) IE 1st jump = "Floppy Fisk A:" 2nd jump = "Sets Floppy Disk A type to blah blah..." If the 2nd table is 00 00, node is terminated there is no 2nd ref. Probably just a blank space or information field. So with this example the BIOS setup screen; the word Main shows up with nothing in the second field.

    The calling jump will be linked to the first byte location; 11AD: in the format AD 11
    Code:
    0170h: 00 00 AD 11 8E 01 99 11 0E 03 B7 11 52 06 37 1F  ............R.7. 
    0180h: 56 09 A7 12 B4 08 A3 11 F4 08 00 00 00 00 33 13  V.............3. 
    0190h: 00 00 23 11 00 00 EF 10 00 00 C1 11 00 00 4F 0C  ..#...........O. 
    01A0h: 00 00 C1 11 00 00 31 18 3E 02 25 18 02 02 19 18  ......1.>.%.....
    At location 0172: you see AD 11 8E 01. This is the beginning of ROOT for the menu items. It is one continous jump and return. 0000 0000 ends the node and sends return back. 11AD is [Main] linked to offset 018E in nodes. So jump to 11AD get info until 0000, return and check if we are linked or 0000. It's linked to 018E, jump to 018E until 0000 then return. Goto 1199 [Advanced] return, jump to 030E till 0000 return. These first rows are your front page in BIOS Setup. Now if the first link had 0000 next to 11AD we jump to next table 1199 instead. AD 11 00 00 99 11 0E 03. This means there is nothing linked to 11AD. Just goto 11AD get the data from strings and return back, jump to 1199.

    11AD Main
    1199 Advanced
    11B7 Security
    1F37 Boot
    12A7 Info
    11A3 Exit
    0000 0000 End

    Notice after 0000 is the file offset 018E is linked to [1333] This is the first jump location linked from Main 11AD. So the entire table nodes that are linked to 11AD are read first, the entire contents of Main. Then come back and read entire contents of Advanced, etc. The first jump is to a lower location in the template that is providing info for table entry in strings. Lets follow 1333.

    1333 Node
    Code:
    1333h: 10 0A 00 00 00 00 75 41 69 41                    ......uAiA
    10 = Type General Text, 0A is length then 0000 Blank space just return.

    Return back to 018E, linked? No goto 1123.
    Code:
    1123h: 21 0A 92 08 90 08 E4 36 EF 36                    !......6.6
    21 = Time Len 0A, 1st offset in strings is 0892: 2nd offset is 0890. 36E4 36EF are fillers, jumps to 55 8B nodes.

    Jump to 0892: and 0890 in strings.
    0890h: 2A 31 FD 87 0A 88 45 88 62 88 B0 88 C0 88 C3 88 *1....E.b.......
    ....
    This jumps to 87FD and 312A in strings and look for text, store the values and return to call.
    Code:
    87FD: System Time:
    87F0h: 00 54 4D 31 20 61 6E 64 20 54 4D 32 00 53 79 73  .TM1 and TM2.Sys 
    8800h: 74 65 6D 20 54 69 6D 65 3A 00 43 6F 6E 74 72 6F  tem Time:.Contro 
    312A: Adjust calendar clock...
    3120h: 00 43 79 61 6E 00 4D 44 59 00 41 64 6A 75 73 74  .Cyan.MDY.Adjust 
    3130h: 20 63 61 6C 65 6E 64 61 72 20 63 6C 6F 63 6B 2E   calendar clock. 
    3140h: 0D 0D 3C 54 61 62 3E 2C 20 3C 53 68 69 66 74 2D  ..<Tab>, <Shift- 
    3150h: 54 61 62 3E 20 6F 72 0D 3C 45 6E 74 65 72 3E 20  Tab> or.<Enter>  
    3160h: 73 65 6C 65 63 74 73 20 66 69 65 6C 64 2E 00 53  selects field..S
    Here is an example of one with data fields. The call is coming from a linked chain in the Advanced menu to location 03EE:
    Code:
    0E33	03EE:	00 14 E4 02 E6 02 A7 2A C9 2A 91 2A 9C 2A F8 01 0A 07 12 07
    00 = Pick Field.   14 Length.  02E4, 02E4 call to stings. 2AA7, 2A91, 2A9C Fillers.  [F8 01] Token 1F8. 070A, 0712 Call to strings.
    			02E4: in strings, jumps to "Virtualization Technology:"	 
    			02E6: in strings, jumps to "Select Virtualization.."
    					F8 01		TOKEN 1F8 [50 13 01] START 113, WIDTH 1 (0+1) MAX SIZE 1 [1], 50 MEDIA 0 
    					0A 07 	070A:	Disabled
    					12 07	0712:	Enabled
    Several locations are shared values. Like 070A and 0712 are called to many times as the text is seen many times in your setup menu.

    00 = Pick Field
    01 = Pick Field
    10 = Generic Text
    11 = Information
    21 = Time
    22 = Date
    23 = Free form Hex
    more

    As long as there is a return closing the node 0000, you can call to locations that are not in your menu screen. There are several tables that call to the same Blank space, this is just for spacing on your setup menu. If you know where the lower table entry is, swap out the call location to your menu you want displayed. Store it in the same pattern. So if I wanted to replace blank space with VT Bit, change the call 33 13 to 33 0E. Sometimes 0000 0000 has been entered to terminate the node menu, insert a call location to the blank space or other menu item so the jumps continues on to the disabled options. You can find these by following the calls to linked menus. The final call should end 0000 0000, the next address should be linked to the next menu item in return call. If it's not linked to anything above, this is an inserted terminated return to hide those options. Insert a call to black space, next time the menu is read those options should be visible. You can verify this with PBE. After you edit the templat0.rom, rebuild the rom, save and open the new rom. Click the setup menu and you should see them listed, click emulate.

    Some roms like this one, the items in the menu are disabled another method. I am still looking to prove the reason. I think it has something to do with the hole.rom. There is another table inside the setup listed under $PDW string in the template. I have not looked much further into this one.
    Code:
     
    0AA0h: 00 00 D4 08 F6 04 C8 02 00 00 24 50 44 57 01 00  ..........$PDW.. 
    0AB0h: E2 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................ 
    0AC0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................ 
    0AD0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................ 
    0AE0h: 00 00 2E 83 3E BC 0A 05 0F 83 AA 00 2E 89 2E BA  ....>........... 
    ..
    If anyone has some corrections or add on please let me know. This is still a work in progress. Knowing how the table is called, you control what is shown. Unlocking the setup could open up some more mods methods. The hole locations seem to store some info from the CMOS and DMI set by the OEM. The store method has been similar. locations with types, length and check sums. Tables stored in bits that can be mapped out with byte tables...

    credit to some of the info
    Examples on understanding the PDM and NVRAM http://intuitivenipple.net/bios/example/
    wimbios thread on hacking nvram posted by intuitivenipple
    intel and phoenix bios docs
    symcmos ftp://ftp.supermicro.com/utility/Phoenix_bios_utility/
    symcmos and nvram, other phoenix tools http://www.users.on.net/~fzabkar/BIOSutil/Phoenix/
    ndisasm http://sourceforge.net/projects/nasm/
    ida http://www.hex-rays.com/idapro/idadownfreeware.htm
    insight debug http://www.bttr-software.de/products/insight/
    olly debug http://www.ollydbg.de/
    fujitsu bios file used to ref n6410 bios 1.09 http://support.fujitsupc.com
    Last edited by rbjack; 11-19-2009 at 05:30 PM. Reason: sPeL chak. minnor correction

  2. Join Date
    Nov 2009
    Posts
    32
    Rep Power
    5

    Thanks, I've been looking into this.

    HP's F.59 A Bios:

    Code:
    (   SYMBOLIC CMOS EDITOR - Version  643710-035   )
    
       System_Configuration
          Language
             ( token 0x28B  start 0x10A  width 0x4 )
             ( maximum 0xF  default 0x0  PICK_FIELD )
                =*  [0]  English_(US)
                =   [1]  Franáais(FR)
                =   [2]  Espa§ol_(SP)
    
       System_Configuration
          Button_Sound
             ( token 0x1CE  start 0x1E8  width 0x1 )
             ( maximum 0x1  default 0x1  PICK_FIELD )
                =   [0]  Disabled
                =*  [1]  Enabled
    
       System_Configuration
          Virtualization_Technology
             ( token 0x14D  start 0xF7  width 0x1 )
             ( maximum 0x1  default 0x0  PICK_FIELD )
                =*  [0]  Disabled
                =   [1]  Enabled
    
       System_Configuration
          Processor_C4_state
             ( token 0x1D1  start 0x1E9  width 0x1 )
             ( maximum 0x1  default 0x1  PICK_FIELD )
                =   [0]  Disabled
                =*  [1]  Enabled
    
       System_Configuration
          Boot_Options
             F10_and_F12_Delay_(sec)
                ( token 0x177  start 0xFF  width 0x3 )
                ( maximum 0x7  default 0x0  PICK_FIELD )
                   =*  [0]  0
                   =   [1]  5
                   =   [2]  10
                   =   [3]  15
                   =   [4]  20
    
       System_Configuration
          Boot_Options
             CD-ROM_Boot
                ( token 0x17A  start 0x102  width 0x1 )
                ( maximum 0x1  default 0x1  PICK_FIELD )
                   =   [0]  Disabled
                   =*  [1]  Enabled
    
       System_Configuration
          Boot_Options
             Floppy_Boot
                ( token 0x17D  start 0x103  width 0x1 )
                ( maximum 0x1  default 0x1  PICK_FIELD )
                   =   [0]  Disabled
                   =*  [1]  Enabled
    
       System_Configuration
          Boot_Options
             Internal_Network_Adapter_Boot
                ( token 0xF9  start 0xC9  width 0x1 )
                ( maximum 0x1  default 0x0  PICK_FIELD )
                   =*  [0]  Disabled
                   =   [1]  Enabled
    Gateway's Godzilla DUMPED on the HP( I know it's no good ):

    Code:
    (   SYMBOLIC CMOS EDITOR - Version  643710-035   )
    
       Advanced
          Legacy_USB_Support:
             ( token 0x450  start 0x154  width 0x1 )
             ( maximum 0x1  default 0x1  PICK_FIELD )
                =   [0]  Disabled
                =*  [1]  Enabled
    
       Advanced
          Extreme_CPU_Speed
             ( token 0x1EF  start 0x60  width 0x8 )
             ( maximum 0xFF  default 0x0  PICK_FIELD )
                =   [0]  _2.6_GHz
                =   [1]  _2.8_GHz
                =   [2]  _3.0_GHz
                =   [3]  _3.2_GHz
                =   [4]  _3.4_GHz
                =   [5]  _3.6_GHz
    
       Advanced
          SATA_Controller_Mode_Option:
             ( token 0x58E  start 0x320  width 0x1 )
             ( maximum 0x1  default 0x0  PICK_FIELD )
                =*  [0]  Compatibility
                =   [1]  AHCI
    
    
       Advanced
          Auto_Dim
    
             ( token 0x1B  start 0x56  width 0x1 )
             ( maximum 0x1  default 0x0  PICK_FIELD )
                =*  [0]  Disabled
                =   [1]  Enabled
    
       Advanced
          Boot_Display
             ( token 0x1E6  start 0x50  width 0x8 )
             ( maximum 0xFF  default 0x0  PICK_FIELD )
                =   [0]  Auto
                =   [1]  Both
    
       Advanced
          Quiet_Boot:
    
             ( token 0x1EC  start 0x59  width 0x7 )
             ( maximum 0x7F  default 0x0  PICK_FIELD )
                =   [0]  Enabled
                =*  [1]  Disabled
    
       Advanced
          _SATA_RAID_Enable
             ( token 0x5BB  start 0x324  width 0x1 )
             ( maximum 0x1  default 0x0  PICK_FIELD )
                =*  [0]  Disabled
                =   [1]  Enabled
    
       Security
          Password_on_boot
    
             ( token 0x31E  start 0x170  width 0x1 )
             ( maximum 0x1  default 0x0  PICK_FIELD )
                =*  [0]  Disabled
                =   [1]  Enabled
    I'm working on Adding Support for the X9000/X7800/X7900 to HP's F59 A Bios.
    Last edited by Darth_nVader; 11-19-2009 at 06:22 PM.

  3. Join Date
    Sep 2009
    Posts
    84
    Rep Power
    21

    If the option has a token id then you can edit the hard coded nvram table for the std defaults and mfg defaults. The BIOS setup maps the values from the NVRAM tokens. Once you make the changes, you must reset the bios to load defaults to take effect. For instance the VT bit on mine is hidden in the setup menu, I can see it in PBE but not when I run the setup menu at boot up. So no menu to change the settings but the settings can be changed by editing the defaults in the NVRAM table. Make the changes, rebuild the rom, flash it and reset to defaults.
    Some of the bit can be controlled by using the symcmos tool. Use the -L option to dump the stored bits. Then use the -U option to set those bits that need changed from the literal dump file. Some functions are locked though. Some require more than one bit enabled. Some settings are lost soon as the power cycle happens. This can only be determined by disassemble the module making the call. On my VT bit a check on another token value was made before even checking the VT bit token. If the first token is disabled it won't even check the VT bit. Enabling the bit in std and mfg defaults over rode that check.

  4. Join Date
    Nov 2009
    Posts
    32
    Rep Power
    5

    I noted the same thing for the VT enable Menu, shows when I Emulate in PBE, but not in the Bios Setup.(F59A)

    I assumed that it was my T5550, as it does not Support VT.

    I've been looking for the MSR bit that disables/enables it, maybe it can be hacked.

    I've also been looking to see if I could Unlock the Multiplier on the T5550, it seems to be set in MSR @17h the IA32_PLATFORM_ID for Merom.

    A 64bit Register, Bits 52 51 50 are for the Intended Platform, I think 1 1 1 is Santa Rosa.

    Bit 28 a value of 1 = Mobile CPU

    Bit 27 1=ES 0=Production CPU

    Bit 26 25 24 are the L2 Cache Size (0 1 0 is 2MB) (0 0 0 is 4MB)

    Bit 15 is Ratio Locked<---This is an odd one, I can give the description, if anyone wants to know.

    Bits 12 11 10 09 08 are the Maximum Frequency( Bus Ratio )
    Bit 12 is the 1/2 multiplier 11-08 are full multipliers
    Bits 0-5 are the Vcc Max

    This MSR seems to be Locked, however poking around in the UPDATED0.ROM at the CPU MicroCode (patches), it looks like the Bios writes 9A708B24 to the first 32bits of MSR@17h.

    I edited the UPDATED0.ROM and flashed it, however no change, but it could be that I'd have to Change the CPUID value in NVRAM, as I understand it the Bios only Uploads the
    MicroCode if the CPUID has Changed.

  5. Join Date
    Sep 2009
    Posts
    84
    Rep Power
    21

    If your CPU supports the VT then try setting the bit enabled in the NVRAM. You can see the menu in PBE emu then you can see it in the setup template. Change the default settings in PBE to enabled and build the BIOS. PBE will change the defaults in the NVRAM token table for you if that option is visible and selectable, mine is selectable. This does not enable the menu for it, it changes the flag in the defaults to enabled. After reboot, load the default settings for the bios, save and reboot. VT should be enabled. check with http://www.grc.com/securable.htm
    patching before the MSR, you need to find the call that pushes the token id. on the return it do a cmp or test jmp that will either set carry bit or clear carry bit. Normally the one that jumps if not zero write locks the msr and ret to call location. but if setting the defaults to enabled overrides that check, no need to patch...
    If you can find the text string that refers to that multiplier option, back trace the offset bytes from strings to nodes. replace a jump to blank space node with the offset of the node you want to enable. If it is not being disabled by the same method VT is hidden it will show up in the BIOS. Even if it doesn't show up in the BIOS, PBE should see it now. The defaults might be selectable... Mod it and load the setup defaults on next boot.

  6. Join Date
    Sep 2009
    Posts
    84
    Rep Power
    21

    Here is a small example color coded to help see the code. The screen shots are from Toshiba Sat P105-S9722 4.70, before and after mod.
    00 00 byte was replaced with 8F 09 in templat0.rom, the menu offset location for VT Bit. 098F is not linked to any other node. Inserting the byte at the termination 0000 for menu Advanced. Because no 0000 0000 follows the bytes being replaced the node continues to other menus that were not visible before either... Because this enabled the menu in the BIOS Setup, there is no need to modify the token bit table in ROMEXEC. Let the BIOS Setup, enable or disable the bit. You can enable and disable on every reboot.
    If you had modified the token bit table, the menu would not be enabled in the BIOS. The defaults would change but the VT bit would not be enabled until you reset the defaults or cleared the CMOS. You can not disable the VT bit unless you flash the bios again with older bios.
    Using the symcmos tool with -U -L option (0219) [0001] may or may not enable VT. some tokens can be set, some can't.
    Attached Images
    Attached Files

  7. Join Date
    Sep 2009
    Posts
    22
    Rep Power
    7

    Ah ok it all makes sense looking at those notes now, but instead of adding 8F 09 at 0x20c can't you overwrite one of the blank spaces (05 16) at 0x204 and get the same result but without those extra options that show up?

    It doesn't show in PBE, but those extra options make a scrollbar show up on the side and it cuts off the last character of "Performance". I made the change on mine and it no longer has that problem, the virtualization option shows up between Execute-Disable Bit and Core Multi-Processing. Thanks again for your help

  8. Join Date
    Sep 2009
    Posts
    84
    Rep Power
    21

    Yeah you can substitute it in place of a call to blank space. You could substitute any item in the bios menu you don't want. I have not tested inserting padding bytes yet, making the templat0.rom larger for custom menus. If there is a large submenu that is hidden, there is probably room to add it as part of the root menu if it was intentionally left out.
    Part of the documentation from Phoenix states the format allows them to quickly integrate into another machine. Of course you can not just swap out a template and strings from another machine. Like many of the offbrand notebooks, the same internals are often found in brand name machines. Sold the same parts from same mfg. The firmware strings are rebadged with the oem name. Comparing some of the templates and strings they are very close to being the same. Looked a few Acer's and they use the same crippled firmware on several models. Fujitsu, some firmware are the same on different models going back for last two years. Yet a newer model may post an update for Win 7 but they don't update the older model. Point being, you can make assumptions some items like the token ID's will match. Observe what is the same and what makes them different across the firmware modules, ie bootblock, romexec, dmi, hole roms and templates. - excluding the info that is preloaded into hole roms. These values can be seen by using the bios dump tool found in the tools thread. Create a dump rom and unpack it into modules. Compare that with the oem unpacked firmware, you will find the hole roms now contain info about your machine shipped from oem. part numbers, serial number, uid, os installation, configurations, etc. This is not the same as what can be found in DMI but does contain some matching items.

+ Reply to Thread

Similar Threads

  1. All Slics - tested and not tested
    By GraceSlic in forum Bios Mods
    Replies: 306
    Last Post: 02-07-2010, 12:09 AM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts