What do you know about BIOS NVRAM hacking?

Only for programmers and BIOS gurus with technical questions.
IntuitiveNipple
BIOS Newbie
Posts: 31
Joined: Tue May 29, 2007 12:24 am

Yes, I use IDA Pro extensively. I recently used it to reverse-engineer the Sony Notebook Control Windows driver, and am using that as the basis to write a complete implementation for Linux: a kernel-driver (snc.ko) and user-space + Gnome control apps.

In real-mode 6CE8h:0E6FE4313h is the address of the Phoenix Dispatch Manager - dispatchManager(...) described above.

I had a novel experience earlier. I fetched the FreeDOS floppy boot image and put it on a real floppy diskette, with symcmos.exe on another diskette. Rebooted the laptop with 'Boot from External Drive' enabled using a USB diskette drive.

Had some issues working out what to do with symcmos.exe.

Code: Select all

A:\ symcmos.exe -Ssymbol.txt
failed with a one-line report about a return code. I forgot to pipe the error report to a file so I can't reproduce it here (until I reboot again). However

Code: Select all

A:\ symcmos.exe -Lreport.txt
did work and I have the file to hand. The first thing I noticed was the CRC reported:

Code: Select all

(   SYMBOLIC CMOS EDITOR - Version  643710-032   )

(   BIOS Version: NAPA0001.86C.0032.D.0702051952     )



CRC = 2786
and the other thing is 0x0676 (1656) bytes of NVRAM reported.

I'm writing a simple script to write the values to a binary file and then run the 'standard' checksum algorithm on them, see if it comes up with 0x2786 (I assume that is hex).

If it does we don't need to hunt for the algorithm, we just need to find where the checksum is stored! It apparently being a 16-bit value gives me hope on that.

It seems strange how the offsets increment by 3, but the values reported are 16-bit.

How did you decide/discover to change 0x0399 to enable VT for your R0092N0 ?

From what I've seen of all the Vaio BIOS images I've explored Phoenix make everything modular so storage locations in NVRAM should be the same across all similar Phoenix versions.

That said, I have:

Code: Select all

(0381) [0001]
(0384) [0000]
(0387) [0000]
(038D) [0001]
(0399) [0003]
(039C) [0000]
(039F) [0002]
(03A2) [3FFF]
(03A5) [000F]
(03A8) [003F]
(03AB) [0000]
(03AE) [0000]
What does yours show for that same range?
IntuitiveNipple
BIOS Newbie
Posts: 31
Joined: Tue May 29, 2007 12:24 am

In symcmos.exe getModuleAddress() (aka sub_3F3A) makes a call to the PDM using a slightly different prototype to the one I deduced previously:

Code: Select all

extern unsigned short dispatchManager(unsigned char, unsigned short, unsigned long, unsigned short);

unsigned long getModuleAddress(unsigned short moduleID) {
 unsigned long moduleAddress;
 unsigned short err;
 unsigned long ptr_dwPDM;
 unsigned long ptrDispatchManager;

 ptr_dwPDM = addrPDM;
 ptrPDM = addrPDM;

 if ( (err = dispatchManager(1, moduleID, moduleAddress, register_SS)) != 0) {
   printError("Return code = %X, Module ID = %X, Module Address = %lX\n", err, moduleID, moduleAddress);
 }
 return moduleAddress;
}
So it appears the 3rd argument (in this case at least) receives a return value.

Coincidentally that is also the error report I saw trying to use the command-line option "-S".
IntuitiveNipple
BIOS Newbie
Posts: 31
Joined: Tue May 29, 2007 12:24 am

I'm working through reverse-engineering all of symcmos so I can write a Linux version that can be run from the boot menu rather like memtest86 is.

I was looking at bobsmit's comments (over at VMTN) and yours about ESID. I infer that ESID[3:2] = 01b means:

"Set bits 3 and 2 to the binary value 01 in register location ESID"

I'm not sure right now where or what ESID is (I assume it is the symbol for one of the NVRAM locations).

In the context of memory management ESID is Effective Segment ID.

I checked the R0200J3 BIOS modules and there's no string similar to the reported "Debug Intel Menu" - I didn't remember seeing anything like that when using Phoenix BIOS Editor either. Do you have it in your BIOS? If so, in which module?

Also, are you able to get symbolic names using symcmos -S ? From my reverse-engineering I can see the symbols are loaded from BIOS but as I said earlier, with the FE41Z and R0200J3 it throws an error.
IntuitiveNipple
BIOS Newbie
Posts: 31
Joined: Tue May 29, 2007 12:24 am

I think I've cracked how it all hangs together.

The (Token) numbers reported in the output of symcmos.exe:

Code: Select all

A:\ symcmos.exe -Lliteral.txt

(   SYMBOLIC CMOS EDITOR - Version  643710-032   )

(   BIOS Version: NAPA0001.86C.0032.D.0702051952     )

CRC = 2786
(0000) [0001]
(0003) [0001]
(0006) [0001]
(0009) [0000]
(000C) [0000]
(000F) [0000]
(0012) [0000]
(0015) [0000]
are the same numbers that are used by the BIOS configuration calls to 0xF000:4120, and the prototype will be something like

Code: Select all

boolean is_nvram_token_enabled(unsigned short Token); 
Here's the R0200J3 BIOSCOD6.ROM extract:

Code: Select all

        mov ecx,0x3a ; MSR 0x3A
        rdmsr ; get current value
        bt eax,0x0
        jc nextSetting ; MSR 0x3A locked so skip trying to change it
        push ax
        mov ax,0x195 ; NVRAM Token # 0x0195
        call 0xf000:0x4120 ; boolean is_nvram_token_enabled(unsigned short Token);
        pop ax
        jz lockMSR ; skip enabling VT if Token # 0x0195 == 0
        bts eax,0x2 ; Enable VT
lockMSR:
        bts eax,0x0 ; Lock MSR until power cycle
        wrmsr
nextSetting:
        xor eax,eax
I scanned all the BIOS modules for "call 0xF000:0x4120" and checked the value placed in the AX register as the parameter to the call. In all cases I've found so far, this number is a multiple of 3 and matches the Token numbers in the output from symcmos.

Some Token-numbers appear in the BIOS that aren't reported by symcmos but that is easily explained by the modular nature of the BIOS - some Token-numbers simply won't be used by the particular PC.

Based on this I am predicting that on this R0200J3 Vaio that Token 0x0195 is the one controlling VT. I've created a custom literal.txt and will be rebooting to FreeDOS shortly to try loading this.

I'm not yet clear how the CRC is handled - presumably symcmos first compares the current CRC with the one in the file, and if they match, then goes ahead and makes the changes to NVRAM. It then updates the system CRC.
If that is correct then when I do:

Code: Select all

A:\ symcmos.exe -L
again the CRC should reflect the change and Token 0x0195 should be 0x0001.

From looking at the symcmos -SSYMBOL.TXT command it appears that originally it was intended that the BIOS contain the symbol-set but it has since been removed. I'll do more digging on this since if we can find a way to match Tokens with symbols we have a sure-fire way to confidently alter settings.

I'm going to extract the BIOS modules from the R0092N0 BIOS image later and confirm that it uses AX=0x0399 in its call to is_nvram_token_enabled(AX).

If all this proves out, getting a Linux version of symcmos written will provide much-needed hacker capability around Phoenix BIOS configuration.

The only mention I could find of VT in the R0200J3 BIOS is this in STRINGS0.ROM:
When enabled, a VMM can
utilize the additional
hardware capabilities
provided by Vanderpool
Technology
Virtualization Technology
Last edited by IntuitiveNipple on Fri Sep 14, 2007 2:41 pm, edited 1 time in total.
bfroemel
New visitors - please read the rules.
Posts: 7
Joined: Wed Sep 12, 2007 10:37 pm

What does yours show for that same range?
It's there, but at a different offset:

Code: Select all

(0438) [0002]

(043B) [0000]

(0441) [0000]

(0444) [0001]

(0450) [0003]

(0453) [0000]

(0456) [0002]

(0459) [3FFF]

(045C) [000F]

(045F) [003F]

(0462) [0000]

(0465) [0000]
So within a module the order is probably kept, but not the overall module order.

Also, the gaps are different (at the same range):

Code: Select all

(0369) [0001]

(0387) [0000]

(038A) [0005]

(0390) [0001]

(0399) [0001]

(039C) [0000]

(039F) [0000]

(03A2) [0000]

(03A5) [0001]

(03A8) [0000]

(03AB) [0000]

(03AE) [0000]
My last entry in the list is

(0711) [0001]
How did you decide/discover to change 0x0399 to enable VT for your R0092N0 ?
trial/error
Do you have it in your BIOS? If so, in which module?
It's a menu entry in the templat0.rom module like any other, only that it seems to be conditional on ESID[3..2], if the help-text can be trusted.
Also, are you able to get symbolic names using symcmos -S ? From my reverse-engineering I can see the symbols are loaded from BIOS but as I said earlier, with the FE41Z and R0200J3 it throws an error.
Here too. The procedure to get symbolic names from a real mode bios call could have simply changed over time or is gone completely: the tool is pretty old and it would have been way tooooo easy if we had symbolic names here! :)
In the context of memory management ESID is Effective Segment ID.
No - it must be something like a complete or part of a serial number/tracking number; something they can change on a per-system base; probably unchangeable without special tools or at all (OTMs).
IntuitiveNipple
BIOS Newbie
Posts: 31
Joined: Tue May 29, 2007 12:24 am

bfroemel wrote:
Do you have it in your BIOS? If so, in which module?
It's a menu entry in the templat0.rom module like any other, only that it seems to be conditional on ESID[3..2], if the help-text can be trusted.
I assume you refer to the menu-entry in templat0.rom based on Phoenix BIOS Editor's presentation of the deconstructed BIOS? Looking at the raw TEMPLAT0.ROM here it is mostly a series of lookup tables with pointers into STRINGS0 and, I would guess, associated Token numbers. There are no strings in the module.
In the context of memory management ESID is Effective Segment ID.
No - it must be something like a complete or part of a serial number/tracking number; something they can change on a per-system base; probably unchangeable without special tools or at all (OTMs).
I don't think so. My guess is that like with many hardware representations each Token aka register aka setting is represented by a 4-character label. These will be declared in a header file for the BIOS as #defines. Additionally, there is likely a string-array containing them that can be built into the BIOS, which is what symcmos -S can interrogate.

So ESID will refer to a Token, and [3:2] tells us which bits control the menu operation.

I have a vast archive of Sony BIOS images going way-back as research material. I think it's time to start collecting Phoenix BIOS images in general, especially older ones that contain the symbols so we can get to know some Token symbols and give clues to others.
IntuitiveNipple
BIOS Newbie
Posts: 31
Joined: Tue May 29, 2007 12:24 am

Happily it worked.

Code: Select all

$ rdmsr 0x3A
5
That shows bit-2 (0x04) and bit-0 (0x01) of MSR 0x3A are set. bit-2 is the VT enable bit.

Loading the Linux KVM modules works and there are no error reports in /var/log/kern.log:

Code: Select all

$ sudo modprobe kvm-intel
$ lsmod | grep kvm
kvm_intel              24720  0 
kvm                    74448  1 kvm_intel
If VT wasn't enabled, kern.log would have shown:

Code: Select all

kernel: [  227.215440] kvm: disabled by bios
So now my intention is to complete the reverse-engineering of symcmos and create a Linux version, and to try and track down as many symbols from Phoenix BIOS images as I can.
bfroemel
New visitors - please read the rules.
Posts: 7
Joined: Wed Sep 12, 2007 10:37 pm

I assume you refer to the menu-entry in templat0.rom based on Phoenix BIOS Editor's presentation of the deconstructed BIOS? Looking at the raw TEMPLAT0.ROM here it is mostly a series of lookup tables with pointers into STRINGS0 and, I would guess, associated Token numbers. There are no strings in the module.
Of course. My understanding of the bios modularization is as follows: Every module can have configuration fields. Each of this configuration fields has space in nvram to store current configuration values and it also has default values. Now, if something should be changeable by the user - a menu field can be added to the template/setup modules and linked to this specific field + a string + a help string. Menu entries can be grouped to menu pages and they can be organized in a tree-like manner (menu, submenu, aso.) . The menu has nothing to do with the module itself where it only refers to; in fact the menu can even be deleted and it would not effect anything (beside that the user won't be able to change settings conveniently). So I assume that you simply don't have this "Debug Intel Menu" page, but mine is there and the logic to display it conditionally must be in templat0/setup0. The strings which it refers to are in the string module.
I don't think so. My guess is that like with many hardware representations each Token aka register aka setting is represented by a 4-character label. These will be declared in a header file for the BIOS as #defines. Additionally, there is likely a string-array containing them that can be built into the BIOS, which is what symcmos -S can interrogate.
This could be true for all user changeable settings beside of passwords and fingerprint compare data.
So ESID will refer to a Token, and [3:2] tells us which bits control the menu operation.
Assuming that the helptext is correct. But there is no need of ESID beeing a parameter in nvram.
btw: ESID won't help in general at all - it would only help SZ-series users and who knows how long.. Sony is listening! :)
I have a vast archive of Sony BIOS images going way-back as research material. I think it's time to start collecting Phoenix BIOS images in general, especially older ones that contain the symbols so we can get to know some Token symbols and give clues to others.
Sounds like a time-consuming but good idea!
Happily it worked.
Great!
IntuitiveNipple
BIOS Newbie
Posts: 31
Joined: Tue May 29, 2007 12:24 am

I've been doing some scanning of /dev/mem with a userspace application with superuser privileges and made quite a bit of progress in finding the location of the Phoenix Dispatch Manager routine in a generic way.

After opening /dev/mem as a file with open() I use the same technique that symcmos uses to locate the PDM structure, but starting at 0 rather than 0xF0000000 as it does.
  1. for ( pos = 0; pos < max_address; pos += 16)
  2. Look for the signature "$PDM" at pos
  3. Check the byte_count value (pos + 0x05) is > 0
  4. Calculate the checksum of bytes pos to pos+byte_count-1
  5. If the checksum is correct (== 0) then:
  6. Read the (far) address of dispatchManager() from pos+7 (4 bytes)
  7. Seek to the address and read the asm JMP seg:offset
  8. Seek to seg:offset and scan asm instructions looking for 'call near [cs:di+OFFSET]' (byte-codes 2E FF 95)
  9. Seek to OFFSET and read 0x0E word entries from the table
The resulting table is the near call offsets for dispatchManager() sub-functions 0 - 0x0D.

Here's an example of the output from the R0200J3 BIOS:

Code: Select all

$ sudo ./find-pdm 

find-pdm version 0.1 © 2007 TJ http://intuitivenipple.net
Licensed on the terms of GPL version 3

Finds Phoenix Dispatch Manager (for supported BIOS's only).

0xFFFFFFFFFFFFFFFF Memory size
0x00000000000F7300 2450444D010B65029800F00000000000 PDM @ 00000000F0009802 sum: 0
Seek to 0x000F9802 readable
Jump to 0xE6FE:4313 (0x000EB2F3)
Table starts at 0xEB2D7
00 (0x000EB2D7) 0x4340
01 (0x000EB2D9) 0x435C
02 (0x000EB2DB) 0x4363
03 (0x000EB2DD) 0x436A
04 (0x000EB2DF) 0x4383
05 (0x000EB2E1) 0x4435
06 (0x000EB2E3) 0x4442
07 (0x000EB2E5) 0x444F
08 (0x000EB2E7) 0x445C
09 (0x000EB2E9) 0x4396
0A (0x000EB2EB) 0x4469
0B (0x000EB2ED) 0x43AE
0C (0x000EB2EF) 0x43CC
0D (0x000EB2F1) 0x4349
It looks from this as if it will be possible to have a user-space application in a regular linux session (not a separate real-mode boot) that can make calls to dispatchManager().

I've got to test calling into it yet but assuming I can figure that out, It looks like it is relatively straightforward to write a utility that can call dispatchManager() that can work with almost all Phoenix BIOSs.

The next step is to use the same memory-search mechanism to scan the full 1MB BIOS image, find the setup module, locate the correct rdmsr/wrmsr 0x3A instructions and the related Token value loaded into AX.

If this works across BIOS versions then the utility can quickly and easily detect the correct VT Token without needing CMOS symbols, or needing to recreate the symcmos utility.
checks
New visitors - please read the rules.
Posts: 1
Joined: Fri Sep 21, 2007 11:01 am

What's the latest regarding enabling VT support on Sony Vaio's?

I've got a AR31S
IntuitiveNipple
BIOS Newbie
Posts: 31
Joined: Tue May 29, 2007 12:24 am

So far, so good. I'm working with libx86 so the utility can run on 32- or 64-bit systems and make real-mode calls into the BIOS. It is the same library used by vbetool.

libx86 combines Linux Real Mode Interface (LRMI) for x86 32-bit and x86emu for 64-bit.

I'm fixing up some 64-bit bugs in libx86 right now. Once I'm happy with it I can link it to VT-enable.

From that point on, assuming the calls into the BIOS complete correctly (in the same way as symcmos calls in) then it is simply a case of tidying it up, documenting, and preparing the Debian/Ubuntu package.
trebiani
New visitors - please read the rules.
Posts: 6
Joined: Mon Aug 13, 2007 9:58 pm

checks wrote:What's the latest regarding enabling VT support on Sony Vaio's?

I've got a AR31S
....and i've got a AR21S and would love to enable VT ;-)
trebiani
New visitors - please read the rules.
Posts: 6
Joined: Mon Aug 13, 2007 9:58 pm

IntuitiveNipple wrote:From that point on, assuming the calls into the BIOS complete correctly (in the same way as symcmos calls in) then it is simply a case of tidying it up, documenting, and preparing the Debian/Ubuntu package.
do you need a beta tester?
right now i'm using ubuntu 7.04 on my sony AR21S
veatnik
New visitors - please read the rules.
Posts: 1
Joined: Wed Oct 10, 2007 11:26 pm

Hi, It is absolutely great to see someone else is also working on this. I have a Sony SZ370P with the same processor and same problem. (Rant: why they disable a key feature on a premium laptop I cannot understand. /Rant)

I used to do this kind of system design/hacking a number of years ago but am a little out of touch as to what tools to use. Was looking at the forums here to get an idea about tools to use when I saw this thread. I'll be happy to help out (but you may be done before I am up to speed) I guess we'll have to see how it goes.

First a related comment: My SZ is about the same vintage as your FE and also specs max ram at 2G. I just upgraded my wife's toshiba (AMD so her virtualization just works (drat)) with a 2G (Centon 2GB667LT available at some mass market outlets for $99) module. So I just thought I should try it in the Sony first. Short story is that each of the memory banks correctly can use it as a full 2G module. The bad news is that if you put two 2G modules in, that the system will only see 3Gs of RAM. (I suspect that another Bios fix might help but I'll back burner that until we get the virtualization going. (I just thought that you might be interested in the potential for 3G or more in your FE. I'll bet that the FE behaves the same as mine.)

The only things I have done so far is to use WinPhlash to get a backup bios. I used an old compaq bios to trigger the ability to backup my bios. I ended up with images that are about 512K in size. I am wondering if I accidently got a partial back up due to the size of the old compaq bios I used.

What size are the Bios images on your FE?

If this is a partial image, what tool would you suggest I use to grab the bios image. (I primarily use Linux but will run XP if needed.)

I'd be happy to provide the images I've got (or get some new images) if that helps you check your work. I'd also be happy to test on this system.

Let me know what I can do to help. In the meantime I'll work on getting tools and getting back up to speed. (If you have suggestions for specific tools that also would be appreciated. I'm happy to write a few tools (on linux only, prefer using LGPL) if you have any ideas for something useful that does not exist (on unix/linux).)

This mechanism you found to use the NVRAM to control some of the BIOS setup probably has other useful application on these laptops. Thanks for the (very) informative post.
IntuitiveNipple
BIOS Newbie
Posts: 31
Joined: Tue May 29, 2007 12:24 am

veatnik wrote:I have a Sony SZ370P with the same processor and same problem. (Rant: why they disable a key feature on a premium laptop I cannot understand. /Rant)
I suspect it's to simplify their support options, since VT is variable across individual models (in the FE41 range, only the "Z" suffix has a CPU with hardware VT).
veatnik wrote:I used to do this kind of system design/hacking a number of years ago but am a little out of touch as to what tools to use.
I downloaded all the integrated BIOS image-installers (.exe executable CAB files) from the Sony Japan FTP site (ftp.vaio.sony.co.jp), and then use cabextract to extract the BIOS image.

It goes something like this:

Code: Select all

$ ls
PHBSYS-01101528-UN.exe

$ cabextract  PHBSYS-01101528-UN.exe 
PHBSYS-01101528-UN.exe: library not compiled to support large files.
PHBSYS-01101528-UN.exe: library not compiled to support large files.
Extracting cabinet: PHBSYS-01101528-UN.exe
  extracting PhlashNT.sys
  extracting R0200J3.WPH
  extracting WBFLASH.exe
  extracting WBFLASH.SCR
  extracting WinPhlash.exe

All done, no errors.

$ ls
PHBSYS-01101528-UN.exe  PhlashNT.sys  R0200J3.WPH  WBFLASH.exe  WBFLASH.SCR  WinPhlash.exe
R0200J3.WPH is the binary image. WPH is the acronym for WinPHlash, the Windows BIOS utility Phoenix provide. You can feed this file into Phoenix BIOS Editor v2.2 (using Wine) and extract the individual modules, images, and relocation information.
veatnik wrote:So I just thought I should try it in the Sony first. Short story is that each of the memory banks correctly can use it as a full 2G module. The bad news is that if you put two 2G modules in, that the system will only see 3Gs of RAM.
Assuming this isn't a hardware limit (address lines tied to zero) then there are two configuration services I can think of that might enable the BIOS recognition of the additional memory:
  1. BIOS Interrupt 0x15 0xE820 function report (aka BIOS-e820)
  2. ACPI DSDT system memory maps (load a custom DSDT)
Do you get the same 3GB limit using a 64-bit operating system? I ask since 32-bit Linux will usually limit userspace to 3GB of RAM because the kernel relocates to the area above that.
veatnik wrote:What size are the Bios images on your FE?

If this is a partial image, what tool would you suggest I use to grab the bios image. (I primarily use Linux but will run XP if needed.)
The R0xxxJ3 BIOSs are 1 megabyte. I described above how I usually isolate them. You could read directly from /dev/mem but since a subset of the BIOS modules is paged into the traditional memory space (0xC8000-0x100000), you would have to identify the mapped location of the entire 1MB image and be sure it hadn't had any run-time fix-ups applied.
veatnik wrote:Let me know what I can do to help. In the meantime I'll work on getting tools and getting back up to speed. (If you have suggestions for specific tools that also would be appreciated. I'm happy to write a few tools (on linux only, prefer using LGPL) if you have any ideas for something useful that does not exist (on unix/linux).)
If you're interested in taking this further then I'd suggest a valuable contribution could be made by developing on my original idea to identify and use the NVRAM Token symbols. That work could be incorporated into a support library that other tools (such as my vt-enable) could call upon for symbolic access to BIOS settings.

It would provide all compatible Phoenix BIOS users with a safe method of interacting with their NVRAM settings using a generic tool. Currently it requires quite a bit of hacking (as you've seen) to identify even one Token with confidence.

From what I've seen so far it'd mainly be a big job of collecting older Phoenix BIOS images from all manufacturers and extracting the symbol tables and then deducing how to apply the information to newer BIOS images that don't contain those symbol tables (The DOS symcmos utility looks for them, and will use the symbols if available - ask me if you want my symcmos code notes). I started the quest but those symbol tables are rare so I suspended my search in favour of more productive hacking.

If it proves infeasible to do it that way, then it'll need a tool that extracts the BIOS modules and then parses them to identify which Token represents which function. My idea would be to do that once on the collected Phoenix BIOS images and create an array of lookup tables in the library code that uses DMI to obtain the running BIOS version and from that determines which entry in the table array matches the BIOS.

You could possibly build on my SNC driver research in doing that.

Now I've got a mechanism to identify the specific NVRAM Token used to enable VT I don't intend taking the Token identification further since I've achieved what I set out to do.

I'll be releasing my vt-enable tool once the Ubuntu Gutsy release is over and I can relax for a while. Some polishing of libx86 has been done so I should be able to use it without a hitch now.
Post Reply