[DISCUSSION] VirtualBox - Update, SLP & SLIC

Discussion in 'Virtualization' started by cigolo_, Dec 30, 2008.

  1. ailin

    ailin MDL Novice

    Nov 9, 2012
    9
    14
    0
    #501 ailin, Feb 7, 2014
    Last edited by a moderator: Apr 20, 2017
    Hi!
    I tried to keep the BIOS functionality as most as possible. There is function _pci16_function located at the offset 0x908a. To keep it working I reassembled the code of this function and cutted off a code branch that have very little chances to be executed. That branch checks for the size of submitted buffer by PCI driver and terminates the rest of execution in case of insufficient buffer size. In normal situation this will never happens. Also note that this code used only for 16-bit native drivers.
    I wrote about that in my previuos message.

    The code marked by red is removed in modified BIOS.

    Code:
    void BIOSCALL PCIxx(function)(volatile pci_regs_t r)
    {
        pci_route_buf __far     *route_buf;
        uint16_t                device;
        SET_AH(SUCCESSFUL);     /* Assume success. */
        CLEAR_CF();
        switch (GET_AL()) {
        case PCI_BIOS_PRESENT:
            AX  = 0x0001;   /* Configuration mechanism #1 supported. */
            BX  = 0x0210;   /* Version 2.1. */
            //@todo: return true max bus # in CL
            CX  = 0;        /* Maximum bus number. */
            EDX = 'P' | ('C' << 8) | ((uint32_t)'I' << 16) | ((uint32_t)' ' << 24);
            break;
        case FIND_PCI_DEVICE:
            /* Vendor ID FFFFh is reserved so that non-present devices can
             * be easily detected.
             */
            if (DX == 0xFFFF) {
                SET_AH(BAD_VENDOR_ID);
                SET_CF();
            } else {
                device = PCIxx(find_device)(DX | (uint32_t)CX << 16, SI, 0);
                if (device == BUSDEVFN_NOT_FOUND) {
                    SET_AH(DEVICE_NOT_FOUND);
                    SET_CF();
                } else {
                    BX = device;
                }
            }
            break;
        case FIND_PCI_CLASS_CODE:
            device = PCIxx(find_device)(ECX, SI, 1);
            if (device == BUSDEVFN_NOT_FOUND) {
                SET_AH(DEVICE_NOT_FOUND);
                SET_CF();
            } else {
                BX = device;
            }
            break;
        case READ_CONFIG_BYTE:
        case READ_CONFIG_WORD:
        case READ_CONFIG_DWORD:
        case WRITE_CONFIG_BYTE:
        case WRITE_CONFIG_WORD:
        case WRITE_CONFIG_DWORD:
            if (DI >= 256) {
                SET_AH(BAD_REGISTER_NUMBER);
                SET_CF();
            } else {
                PCIxx(select_reg)(BX, DI);
                switch (GET_AL()) {
                case READ_CONFIG_BYTE:
                    SET_CL(inp(PCI_CFG_DATA + (DI & 3)));
                    break;
                case READ_CONFIG_WORD:
                    CX = inpw(PCI_CFG_DATA + (DI & 2));
                    break;
                case READ_CONFIG_DWORD:
                    ECX = inpd(PCI_CFG_DATA);
                    break;
                case WRITE_CONFIG_BYTE:
                    outp(PCI_CFG_DATA + (DI & 3), GET_CL());
                    break;
                case WRITE_CONFIG_WORD:
                    outpw(PCI_CFG_DATA + (DI & 2), CX);
                    break;
                case WRITE_CONFIG_DWORD:
                    outpd(PCI_CFG_DATA, ECX);
                    break;
                }
            }
            break;
        case GET_IRQ_ROUTING:
            route_buf = ES :> (void *)DI;
            
            if (pci_routing_table_size > route_buf->buf_size) {
                SET_AH(BUFFER_TOO_SMALL);
                SET_CF();
            } else {
                rep_movsb(route_buf->buf_ptr, pci_routing_table, pci_routing_table_size);
                /* IRQs 9 and 11 are PCI only. */
                BX = (1 << 9) | (1 << 11);
            }
            route_buf->buf_size = pci_routing_table_size;
            break;
        default:
            BX_INFO("PCI: Unsupported function AX=%04X BX=%04X called\n", AX, BX);
            SET_AH(FUNC_NOT_SUPPORTED);
            SET_CF();
        }
    }
    
    
    Asm code is below.
    Code of the specified function will clear description above. The "before" part is the code of original BIOS function and the "after" part is the code of modified BIOS function. I also rearranged some blocks to keep correctness of short jumps.

    Before:
    Code:
    _pci16_function:                             ; 0xf9016 LB 0x1d7
        push bp                                   ; 55
        mov bp, sp                                ; 89 e5
        push si                                   ; 56
        push di                                   ; 57
        push ax                                   ; 50
        push ax                                   ; 50
        and word [bp+020h], 000ffh                ; 81 66 20 ff 00
        and word [bp+02ch], strict byte 0fffeh    ; 83 66 2c fe
        mov bx, word [bp+020h]                    ; 8b 5e 20
        xor bh, bh                                ; 30 ff
        mov ax, word [bp+020h]                    ; 8b 46 20
        xor ah, ah                                ; 30 e4
        cmp bx, strict byte 00003h                ; 83 fb 03
        jc short 0904fh                           ; 72 1a
        jbe short 090a7h                          ; 76 70
        cmp bx, strict byte 0000eh                ; 83 fb 0e
        je near 09174h                            ; 0f 84 36 01
        cmp bx, strict byte 00008h                ; 83 fb 08
        jc near 091b9h                            ; 0f 82 74 01
        cmp bx, strict byte 0000dh                ; 83 fb 0d
        jbe near 090cch                           ; 0f 86 80 00
        jmp near 091b9h                           ; e9 6a 01
        cmp bx, strict byte 00002h                ; 83 fb 02
        je short 09077h                           ; 74 23
        cmp bx, strict byte 00001h                ; 83 fb 01
        jne near 091b9h                           ; 0f 85 5e 01
        mov word [bp+020h], strict word 00001h    ; c7 46 20 01 00
        mov word [bp+014h], 00210h                ; c7 46 14 10 02
        mov word [bp+01ch], strict word 00000h    ; c7 46 1c 00 00
        mov word [bp+018h], 04350h                ; c7 46 18 50 43
        mov word [bp+01ah], 02049h                ; c7 46 1a 49 20
        jmp near 091e6h                           ; e9 6f 01
        cmp word [bp+018h], strict byte 0ffffh    ; 83 7e 18 ff
        jne short 09083h                          ; 75 06
        or ah, 083h                               ; 80 cc 83
        jmp near 091dfh                           ; e9 5c 01
        mov bx, word [bp+008h]                    ; 8b 5e 08
        mov dx, word [bp+01ch]                    ; 8b 56 1c
        mov ax, word [bp+018h]                    ; 8b 46 18
        xor cx, cx                                ; 31 c9
        call 08f1fh                               ; e8 8e fe
        cmp ax, strict word 0ffffh                ; 3d ff ff
        jne short 090a1h                          ; 75 0b
        mov ax, word [bp+020h]                    ; 8b 46 20
        xor ah, ah                                ; 30 e4
        or ah, 086h                               ; 80 cc 86
        jmp near 091dfh                           ; e9 3e 01
        mov word [bp+014h], ax                    ; 89 46 14
        jmp near 091e6h                           ; e9 3f 01
        mov bx, word [bp+008h]                    ; 8b 5e 08
        mov ax, word [bp+01ch]                    ; 8b 46 1c
        mov dx, word [bp+01eh]                    ; 8b 56 1e
        mov cx, strict word 00001h                ; b9 01 00
        call 08f1fh                               ; e8 69 fe
        cmp ax, strict word 0ffffh                ; 3d ff ff
        jne short 090c6h                          ; 75 0b
        mov ax, word [bp+020h]                    ; 8b 46 20
        xor ah, ah                                ; 30 e4
        or ah, 086h                               ; 80 cc 86
        jmp near 091dfh                           ; e9 19 01
        mov word [bp+014h], ax                    ; 89 46 14
        jmp near 091e6h                           ; e9 1a 01
        cmp word [bp+004h], 00100h                ; 81 7e 04 00 01
        jc short 090d9h                           ; 72 06
        or ah, 087h                               ; 80 cc 87
        jmp near 091dfh                           ; e9 06 01
        mov dx, word [bp+004h]                    ; 8b 56 04
        mov ax, word [bp+014h]                    ; 8b 46 14
        call 08efbh                               ; e8 19 fe
        mov bx, word [bp+020h]                    ; 8b 5e 20
        xor bh, bh                                ; 30 ff
        sub bx, strict byte 00008h                ; 83 eb 08
        cmp bx, strict byte 00005h                ; 83 fb 05
        jnbe near 091e6h                          ; 0f 87 f5 00
        add bx, bx                                ; 01 db
        jmp word [cs:bx-06ff6h]                   ; 2e ff a7 0a 90
        mov bx, word [bp+01ch]                    ; 8b 5e 1c
        xor bl, bl                                ; 30 db
        mov dx, word [bp+004h]                    ; 8b 56 04
        and dx, strict byte 00003h                ; 83 e2 03
        add dx, 00cfch                            ; 81 c2 fc 0c
        in AL, DX                                 ; ec
        db  02ah, 0e4h
        ; sub ah, ah                                ; 2a e4
        or bx, ax                                 ; 09 c3
        mov word [bp+01ch], bx                    ; 89 5e 1c
        jmp near 091e6h                           ; e9 d4 00
        mov dx, word [bp+004h]                    ; 8b 56 04
        xor dh, dh                                ; 30 f6
        and dl, 002h                              ; 80 e2 02
        add dx, 00cfch                            ; 81 c2 fc 0c
        in ax, DX                                 ; ed
        mov word [bp+01ch], ax                    ; 89 46 1c
        jmp near 091e6h                           ; e9 c1 00
        mov dx, 00cfch                            ; ba fc 0c
        in eax, DX                                ; 66 ed
        db  08bh, 0d0h
        ; mov dx, ax                                ; 8b d0
        shr eax, 010h                             ; 66 c1 e8 10
        xchg dx, ax                               ; 92
        mov word [bp+01ch], ax                    ; 89 46 1c
        mov word [bp+01eh], dx                    ; 89 56 1e
        jmp near 091e6h                           ; e9 ac 00
        mov ax, word [bp+01ch]                    ; 8b 46 1c
        mov dx, word [bp+004h]                    ; 8b 56 04
        xor dh, dh                                ; 30 f6
        and dl, 003h                              ; 80 e2 03
        add dx, 00cfch                            ; 81 c2 fc 0c
        out DX, AL                                ; ee
        jmp near 091e6h                           ; e9 99 00
        mov ax, word [bp+01ch]                    ; 8b 46 1c
        mov dx, word [bp+004h]                    ; 8b 56 04
        xor dh, dh                                ; 30 f6
        and dl, 002h                              ; 80 e2 02
        add dx, 00cfch                            ; 81 c2 fc 0c
        out DX, ax                                ; ef
        jmp near 091e6h                           ; e9 86 00
        mov ax, word [bp+01ch]                    ; 8b 46 1c
        mov cx, word [bp+01eh]                    ; 8b 4e 1e
        mov dx, 00cfch                            ; ba fc 0c
        xchg cx, ax                               ; 91
        sal eax, 010h                             ; 66 c1 e0 10
        db  08bh, 0c1h
        ; mov ax, cx                                ; 8b c1
        out DX, eax                               ; 66 ef
        jmp short 091e6h                          ; eb 72
        mov bx, word [bp+004h]                    ; 8b 5e 04
        mov es, [bp+026h]                         ; 8e 46 26
        mov word [bp-008h], bx                    ; 89 5e f8
        mov [bp-006h], es                         ; 8c 46 fa
        mov cx, word [0f4a0h]                     ; 8b 0e a0 f4
        cmp cx, word [es:bx]                      ; 26 3b 0f
        jbe short 0919ah                          ; 76 11
        mov ax, word [bp+020h]                    ; 8b 46 20
        xor ah, ah                                ; 30 e4
        or ah, 089h                               ; 80 cc 89
        mov word [bp+020h], ax                    ; 89 46 20
        or word [bp+02ch], strict byte 00001h     ; 83 4e 2c 01
        jmp short 091aeh                          ; eb 14
        les di, [es:bx+002h]                      ; 26 c4 7f 02
        mov si, 0f2c0h                            ; be c0 f2
        mov dx, ds                                ; 8c da
        push DS                                   ; 1e
        mov ds, dx                                ; 8e da
        rep movsb                                 ; f3 a4
        pop DS                                    ; 1f
        mov word [bp+014h], 00a00h                ; c7 46 14 00 0a
        mov ax, word [0f4a0h]                     ; a1 a0 f4
        les bx, [bp-008h]                         ; c4 5e f8
        mov word [es:bx], ax                      ; 26 89 07
        jmp short 091e6h                          ; eb 2d
        mov bx, 00da2h                            ; bb a2 0d
        mov cx, ds                                ; 8c d9
        mov ax, strict word 00004h                ; b8 04 00
        call 018cch                               ; e8 08 87
        mov ax, word [bp+014h]                    ; 8b 46 14
        push ax                                   ; 50
        mov ax, word [bp+020h]                    ; 8b 46 20
        push ax                                   ; 50
        push 00d5eh                               ; 68 5e 0d
        push strict byte 00004h                   ; 6a 04
        call 0190dh                               ; e8 39 87
        add sp, strict byte 00008h                ; 83 c4 08
        mov ax, word [bp+020h]                    ; 8b 46 20
        xor ah, ah                                ; 30 e4
        or ah, 081h                               ; 80 cc 81
        mov word [bp+020h], ax                    ; 89 46 20
        or word [bp+02ch], strict byte 00001h     ; 83 4e 2c 01
        lea sp, [bp-004h]                         ; 8d 66 fc
        pop di                                    ; 5f
        pop si                                    ; 5e
        pop bp                                    ; 5d
        retn                                      ; c3
    

    After (note that labels named in "after" here used just as labels, it names does not correspond to real offset but in "before" it does):
    Code:
    _pci16_function:                             ; 0xf9016 LB 0x1d7
          
      ; 0xf9016
      
      push bp
      mov bp, sp
      push si
      push di
      push ax
      push ax
      and word [bp+20h], 0FFh
      and word [bp+02ch], strict byte 0fffeh
      mov bx, word [bp+020h]
      xor bh, bh
      mov ax, word [bp+20h]
      xor ah, ah
      cmp bx, strict byte 00003h
      jb short loc_F904F
      jbe short loc_F90A7
      cmp bx, strict byte 0000eh
      jz loc_F9174
      cmp bx, strict byte 00008h
      jb loc_F91DF
      cmp bx, strict byte 0000dh
      ;jbe loc_F90CC
      jmp short loc_F90D9
      ;jmp loc_F91DF
    ; ---------------------------------------------------------------------------
    
    loc_F904F:    ; ...
      cmp bx, strict byte 00002h
      jz short loc_F9077
      cmp bx, strict byte 00001h
      jnz loc_F91DF
      mov word [bp+020h], strict word 00001h
      mov word [bp+14h], 210h
      mov word [bp+01ch], strict word 00000h
      mov word [bp+18h], 4350h
      mov word [bp+1Ah], 2049h
      jmp loc_F91E6
    ; ---------------------------------------------------------------------------
    
    loc_F9077:    ; ...
      cmp word [bp+018h], strict byte 0ffffh
      jnz short loc_F9083
      or ah, 83h
      jmp loc_F91DF
    ; ---------------------------------------------------------------------------
    
    loc_F9083:    ; ...
      mov bx, word [bp+008h]
      mov dx, word [bp+01ch]
      mov ax, word [bp+018h]
      xor cx, cx
      call 8F1Fh
      cmp ax, strict word 0ffffh
      jnz short loc_F90A1
      mov ax, [bp+20h]
      xor ah, ah
      or ah, 86h
      jmp loc_F91DF
    ; ---------------------------------------------------------------------------
    
    loc_F90A1:    ; ...
      mov [bp+14h], ax
      jmp loc_F91E6
    ; ---------------------------------------------------------------------------
    
    loc_F90A7:    ; ...
      mov bx, [bp+8]
      mov ax, [bp+1Ch]
      mov dx, [bp+1Eh]
      mov cx, strict word 00001h
      call 8F1Fh
      cmp ax, strict word 0ffffh
      jnz short loc_F90C6
      mov ax, [bp+20h]
      xor ah, ah
      or ah, 86h
      jmp loc_F91DF
    ; ---------------------------------------------------------------------------
    
    loc_F90D9:    ; ...
      mov dx, [bp+4]
      mov ax, [bp+14h]
      call 8EFBh
      mov bx, [bp+20h]
      xor bh, bh
      sub bx, strict byte 00008h
      cmp bx, strict byte 00005h
      ja loc_F91E6
      add bx, bx
      jmp word [cs:bx-06ff6h]
    
     db 0h
     dd 'Windows_Virtual_XP_F9161D8E7FCC11DDBFAA369856D89593'
     dd 0h
     db 0h
    
    loc_F90C6:    ; ...
      mov [bp+14h], ax
      jmp loc_F91E6
    ; ---------------------------------------------------------------------------
    
    ;loc_F90CC:    ; ...
      ;cmp word [bp+4], 100h
      ;jb short loc_F90D9
      ;or ah, 87h
      ;jmp loc_F91DF
    ; ---------------------------------------------------------------------------
    
    loc_F90F8:    ; ...
      mov bx, [bp+1Ch]
      xor bl, bl
      mov dx, [bp+4]
      and dx, strict byte 00003h
      add dx, 0CFCh
      in al, dx
      db  02ah, 0e4h
      ; sub ah, ah
      or bx, ax
      mov [bp+1Ch], bx
      jmp loc_F91E6
    ; ---------------------------------------------------------------------------
    
    loc_F9112:    ; ...
      mov dx, [bp+4]
      xor dh, dh
      and dl, 2
      add dx, 0CFCh
      in ax, dx
      mov [bp+1Ch], ax
      jmp loc_F91E6
    ; ---------------------------------------------------------------------------
    
    loc_F9125:    ; ...
      mov dx, 0CFCh
      in eax, dx  ; PCI Configuration Space Data Register
      db  08bh, 0d0h ; sub ah, ah
      shr eax, 10h
      xchg ax, dx
      mov [bp+1Ch], ax
      mov [bp+1Eh], dx
      jmp loc_F91E6
    ; ---------------------------------------------------------------------------
    
    loc_F913A:    ; ...
      mov ax, [bp+1Ch]
      mov dx, [bp+4]
      xor dh, dh
      and dl, 3
      add dx, 0CFCh
      out dx, al
      jmp loc_F91E6
    ; ---------------------------------------------------------------------------
    
    loc_F914D:    ; ...
      mov ax, [bp+1Ch]
      mov dx, [bp+4]
      xor dh, dh
      and dl, 2
      add dx, 0CFCh
      out dx, ax
      jmp loc_F91E6
    ; ---------------------------------------------------------------------------
    
    loc_F9160:    ; ...
      mov ax, [bp+1Ch]
      mov cx, [bp+1Eh]
      mov dx, 0CFCh
      xchg ax, cx
      shl eax, 10h
      db  08bh, 0c1h    ; mov ax, cx
      out dx, eax  ; PCI Configuration Space Data Register
      jmp short loc_F91E6
    ; ---------------------------------------------------------------------------
    
    loc_F9174:    ; ...
      mov bx, [bp+4]
      mov es, word [bp+26h]
      mov [bp-8], bx
      mov word [bp-6], es
      mov cx, word [0f4a0h]
      cmp cx, word [es:bx]
      jbe short loc_F919A
      mov ax, [bp+20h]
      xor ah, ah
      or ah, 89h
      mov [bp+20h], ax
      or word [bp+02ch], strict byte 00001h
      jmp short loc_F91AE
    ; ---------------------------------------------------------------------------
    
    loc_F919A:    ; ...
      les di, [es:bx+002h]
      mov si, 0F2C0h
      mov dx, ds
      push ds
      mov ds, dx
      rep movsb
      pop ds
      mov word [bp+14h], 0A00h
    
    loc_F91AE:    ; ...
      mov ax, word [0f4a0h]
      les bx, [bp-8]
      mov word [es:bx], ax
      jmp short loc_F91E6
    ; ---------------------------------------------------------------------------
    
    loc_F91DF:    ; ...
      mov [bp+20h], ax
      or word [bp+02ch], strict byte 00001h
    
    loc_F91E6:    ; ...
      lea sp, [bp-4]
      pop di
      pop si
      pop bp
      retn
     
      ; 0xf91ed
    
    

    Also, the string
    Code:
    F000,908A,,Windows_Virtual_XP_F9161D8E7FCC11DDBFAA369856D89593
    is equivalent
    to
    Code:
    F000,908A,104,Windows_Virtual_XP_F9161D8E7FCC11DDBFAA369856D89593
    and 104 is also HEX, i.e. 0x104.
    It means that the string can be placed in 908A....918E and the offset I chose is valid. ;)
     
  2. nerd.brazil

    nerd.brazil MDL Novice

    Feb 5, 2014
    11
    0
    0
    #502 nerd.brazil, Feb 7, 2014
    Last edited by a moderator: Apr 20, 2017
    All I can say is wow! You have clearly explained everything and you did more than I would have done... for future VBox releases, do you think the _pci16_function will remain the same so that you can reuse your hard work?

    Thanks for the clarification on the 104h as opposed to 104d.

    And lastly, forgive me for having this paranoia of a possible BIOS malware when I saw this:

    View attachment 26901

    Left side is original 4.3.6 BIOS and right side is your hacked BIOS (using vimdiff)... I was scared by all that differences! Now I understand. So, just to confirm, you had to recompile VBoxDD2.[DLL|so] from sources with your modified _pci16_function right? Or maybe you just needed to recompile VBoxBiosAlternative.asm.

    Once again, awesome work!

    Further work on this matter, I tried another method: using Virtual PC's own BIOS... since it works perfectly with Windows XP Mode, I assumed that the OEM String is in the BIOS. I ran Resource Hacker on VPC.EXE and extracted the BIOS. It's 256K and a variation of AMIBIOS. I just loaded the BIOS in VirtualBox but the VM did not boot. Any ideas why it doesn't work? Can it work?

     
  3. Tito

    Tito Super Mod / Adviser
    Staff Member

    Nov 30, 2009
    18,682
    18,581
    340
    @nerd.brazil

    You can't use Virtual PC's bios in VirtualBox as they emulate totally different hardwares (like you can't flash Asus K53SC's bios in Asus K55VD).
     
  4. Carlos Detweiller

    Carlos Detweiller Emperor of Ice-Cream

    Dec 21, 2012
    6,316
    7,023
    210
    @tito: I guess t'was just a typo/misspelling. Using such a different BIOS wouldn't even boot.
     
  5. cvachta

    cvachta MDL Novice

    Feb 1, 2014
    2
    0
    0
    #505 cvachta, Feb 15, 2014
    Last edited by a moderator: Apr 20, 2017
    XP mode activation

    I downloaded modified VirtualBox BIOS with added OEM SPL string for Windows XP mode (Windows_Virtual_XP_F9161D8E7FCC11DDBFAA369856D89593), but if I choose SATA controller VM crash.

    So I patched VirtualBox BIOS myself - It works fine when using extradata "VBoxInternal/Devices/pcbios/0/Config/BiosRom" in vbox config via command
    Code:
    VBoxManage setextradata "Windows XP" VBoxInternal/Devices/pcbios/0/Config/BiosRom "/path/to/xpbios.bin"
    SATA works fine! BIOS is from VirtualBox 4.2.16 on Ubuntu 13.10, SPL string (Windows_Virtual_XP_F9161D8E7FCC11DDBFAA369856D89593) is on offset 0x908A.
     
  6. nerd.brazil

    nerd.brazil MDL Novice

    Feb 5, 2014
    11
    0
    0
    [h=2](pardon me for posting this as a new thread... didn't mean to)

    A few questions...[/h]
    I've seen many times people say to just insert the SLP string in the DMI area of BIOS, and when researching this matter I have a few questions:

    1) Isn't DMI a soon-to-be deprecated syntax which is now being superceded by SMBIOS?

    2) They perform similar function in that they provide hardware information to the OS right?

    3) Is the SMBIOS/DMI region inside the BIOS ROM code?

    E.g. VirtualBox's BIOS is 64K in size; it's SMBIOS/DMI Entry Point Table is defined towards the end of the BIOS ROM at offset 0xFF60. It defines the DMI TableAddress to be 0x000E1000 which is outside the BIOS ROM area. I've read that the SMBIOS Tables is created elsewhere and thus I assume that the table is NOT inside the BIOS ROM. "dmidecode" informs that there is no DMI entries.

    What area is the SLP string stored then? Any place that is empty and free of code? People say DMI area... but I can't verify this.

    I understand that sometimes if the SLP string is expected within a wide address range, then adding the string to the XML config file could work. Not so for the Windows XP Mode string. ​
     
  7. jcap511

    jcap511 MDL Novice

    Aug 10, 2013
    13
    2
    0
    Forgive me if there's an obvious answer to this, but is there some advantage to using the "XP Mode" SLP string versus other SLP strings?
    XP will activate in virtualbox just fine by setting the DmiSystemVendor to Dell or Hewlett-Packard and using the corresponding OEMBIOS files for example.

    The only thing I can think of is that XP Mode looks more legitimate? :confused:
     
  8. Tito

    Tito Super Mod / Adviser
    Staff Member

    Nov 30, 2009
    18,682
    18,581
    340
    Exactly what is my thought. Placing the string is like a challenge but optional.

    :D
     
  9. CocoNuts

    CocoNuts MDL Novice

    Sep 23, 2007
    36
    7
    0
    #509 CocoNuts, Feb 26, 2014
    Last edited by a moderator: Apr 20, 2017
  10. nerd.brazil

    nerd.brazil MDL Novice

    Feb 5, 2014
    11
    0
    0
    ailin,

    Once again SUPERB job! May I inquire as to which assembler one needs to use to compile the file:

    VirtualBox-4.3.6/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm

    I tried as86 without success.

    Thanks!

     
  11. ailin

    ailin MDL Novice

    Nov 9, 2012
    9
    14
    0
    nerd.brazil,

    Thank you! :rolleyes:

    To compile VBoxBiosAlternative.asm you need to use yasm assembler.

    Note that the provided BIOS for 4.3.8 was recompiled from it's C sources that made possible to integrate MS SLP code without touching any BIOS function.
     
  12. nerd.brazil

    nerd.brazil MDL Novice

    Feb 5, 2014
    11
    0
    0
    Thanks for the YASM tip...

    I suppose you had to use OpenWatcom compiler in order to compile directly from C sources, right?

    I had thought of another approach and wish to ask you opinion of it: (Using 4.3.6 for this approach)

    From the BIOS.BIN I would copy the entire _pci16_function region and move it towards the end where there is a bunch of 0x00. At the original _pci16_function address I would simply put a JMP command to the new address location. I would then be able to insert the SLP string without messing the _pci16_function. Basically I would manually do in assembly what you managed to do in C. It might be necessary to fix the addresses in the new region, e.g. a relative address to some fixed data.

    What's your thoughts on this?
     
  13. ailin

    ailin MDL Novice

    Nov 9, 2012
    9
    14
    0
    #514 ailin, Mar 1, 2014
    Last edited by a moderator: Apr 20, 2017
    nerd.brazil,
    You're right, to compile C sources of VirtualBox BIOS Open Watcom is needed. By the way, in the tar.gz source archive that can be downloaded from VirtualBox download page the makefile for Open Watcom is outdated and needs to be adjusted to achive byte-to-byte identical BIOS image that provided with VirtualBox distribution.
    Your solution is also can work. But as you said it needs to recalculate some address offsets. As you noticed in one of previous posts this job is needed to repeat each time VirtualBox releases and there is (IMHO) no easy way to make this using only decompiled ASM source.
    I found C sources more prefereable for this task because of at new VirtualBox release we need to:
    1. Compare Makefile.kmk and Config.kmk from new and old releases to find what changed and adjust these changed in makefile for Open Watcom.
    2. Compile BIOS using Open Watcom and found at BIOS map file what occupies the SLP memory region.
    3. Edit needed C source inserting SLP dumb and recompile the BIOS again.
    As you see all ofsets are recalculated by compiler itself and there significantly lesser chance to make a mistake than calculating offsets manually.

    P.S. If you'll like to try compile C sources using Open Watcom this is the adjusted makefile:

    Code:
    # Compiler flags:
    #  -q   no banner
    #  -wx  max warnings
    #  -0   generate 8086 code
    #  -ms  force small model (default)
    #  -s   remove runtime stack checks (required)
    #  -os  optimize for size
    #  -zu  assume that SS != DS (required)
    #  -ecc default to __cdecl calling convention (bad idea)
    #
    !ifdef __UNIX__
    Q=\"
    !else
    Q="
    !endif
    CFLAGS   = -q -3 -wx -zl -zu -s -oafs -ms -hc -d1+
    CFLAGS32 = -q -wx -zu -s -oas -ms -nt=BIOS32 -nd=BIOS32 -hc -d1+
    
    DEFS = -DVBOX -DVBOX_PC_BIOS -DVBOX_LANBOOT_SEG=0xE200 -DVBOX_VERSION_STRING=$(Q)4.3.8$(Q) &
     -DVBOX_WITH_SCSI -DVBOX_WITH_AHCI
    
    AFLAGS = -q -wx -d1
    
    INCLS  = -I$(Q)../include$(Q)
    
    .c.obj : .autodepend
        wcc -fo=.obj $(CFLAGS) $(DEFS) $(INCLS) $<
    
    .asm.obj : .autodepend
        wasm -fo=.obj $(AFLAGS) $(DEFS) $<
    
    OBJS =     bios.obj print.obj ata.obj floppy.obj floppyt.obj eltorito.obj &
        boot.obj keyboard.obj disk.obj serial.obj system.obj invop.obj &
        timepci.obj ps2mouse.obj parallel.obj logo.obj scsi.obj &
        ahci.obj apm.obj pcibios.obj pciutil.obj vds.obj support.obj &
        pcibio32.obj apm_pm.obj pci32.obj orgs.obj
    
    vbxbios.rom : vbxbios.bin
        biossums $< $@
    
    vbxbios.bin : $(OBJS) $(__MAKEFILES__)
        wlink name $@ system dos debug codeview all option quiet &
         option nofarcalls, map, verbose, statics, symfile &
         output raw offset=0xF0000 order &
         clname DATA segaddr=0xF000 segment _DATA &
         clname CODE &
         segment _TEXT segaddr=0xF000 offset=0x1600 &
         segment BIOS32 segaddr=0xF000 offset=0xDA00 &
         segment BIOSSEG segaddr=0xF000 offset=0xE000 &
         file { $(OBJS) } &
         library clibs.lib &
         disable 1014, 1023, 2120
    
    logo.obj : logo.c .autodepend
        wcc -fo=.obj $(INCLS) $(CFLAGS) $(DEFS) -DVBOX_PC_BIOS $<
    
    pci32.obj : pci32.c .autodepend
        wcc386 -fo=.obj $(INCLS) $(DEFS) $(CFLAGS32) $<
    
    clean : .symbolic
        @rm -f *.obj *.err
        @rm -f vbxbios.bin vbxbios.rom vbxbios.map vbxbios.sym
    
    
     
  14. nerd.brazil

    nerd.brazil MDL Novice

    Feb 5, 2014
    11
    0
    0
    #515 nerd.brazil, Mar 3, 2014
    Last edited by a moderator: Apr 20, 2017
    Hi ailin!

    I am happy to inform that I had success with my method! For those reading this now, the attached BIOS retains all its original functionality while still being tattooed with Windows XP Mode SLP string. (VirtualBox 4.3.6)

    It was not difficult at all, I spent most time calculating by hand the relative addresses for the 5 CALLs because for some reason, "radare" hexeditor did not generate the correct disassembly for those CALLs. This method, while being in the realm of reverse engineering, is advantageous in that it does not require the source code, but it definitely speeded up the process...

    These were the hexeditor commands used on an extracted VirtualBox BIOS binary file (I used "radare" version 1 since version 2 had problems disassembling 16-bit code):

    Code:
    # radare -w pcbios.bin
    
    > e asm.arch=intel16 ;only needed if doing disassembly
    > s 0x9016 ;goto the beginning of _pci16_function at address 0x9016
    > y 471 ;the function is 471 bytes long and is copied
    > wx e9 4c 04 ;replaced the function with a simple JMP to the new location 0x9465
    > s 0x9465 ;goto the beginning of the empy space
    > yy ;paste the _pci16_function code
    > s 0x94dd ;goto 1st CALL
    > wx e8 3f fa ;replace with CALL 0x8f1f
    > s 0x9502 ;goto 2nd CALL
    > wx e8 1a fa ;replace with CALL 0x8f1f
    > s 0x952e ;goto 3rd CALL
    > wx e8 ca f9 ;replace with CALL 0x8efb
    > s 0x9610 ;goto 4th CALL
    > wx e8 b9 82 ;replace with CALL 0x18cc
    > s 0x9620 ;goto 5th CALL
    > wx e8 ea 82 ;replace with CALL 0x190d
    > q
    
    I then used "hexeditor" to paste the Windows XP Mode SLP exactly at 0x908a. Works perfectly!

    For those wishing to dig further into this method, here are a few info:

    + Use VBoxBiosAlternative-4.3.6.asm source file from VirtualBox source code.
    + With it you can find which function resides at the SLP region (0x908a-0x918e); in this case _pci16_function
    + You can find out how long this function is; in this case 471 bytes
    + You can find out where the empty space begins after all the code; in this case at 0x9465: 17,819 db 0x00
    + After you move _pci16_function to the new address, check for addresses outside the function memory space and fix it; 5 CALLs found; all the JMPs and its derivatives were local jumps

    Attached is the edited pcbios.bin file for your own analysis.

    (Note: yes, I am a little late to the party since version 4.3.8 is already out... but I do this just for fun! I just got sidetracked with this little project... I never messed with BIOS ROM before hahaha!)

    edit: hmmm... in retrospect I should have edited the ASM file instead and compiled with YASM... but I guess using a hexeditor is waaay cooler!
     
  15. Tito

    Tito Super Mod / Adviser
    Staff Member

    Nov 30, 2009
    18,682
    18,581
    340
    #516 Tito, Mar 25, 2014
    Last edited by a moderator: Apr 20, 2017
  16. nerd.brazil

    nerd.brazil MDL Novice

    Feb 5, 2014
    11
    0
    0
    I just checked the BIOS assembly source and nothing changed other than version number and a checksum digit. You may continue to use BIOS from 4.3.8 without any problems!

    ===

    kali:tmp.r geek504$ diff VBoxBiosAlternative-4.3.8.asm VBoxBiosAlternative-4.3.10.asm
    968c968
    < db 'VirtualBox 4.3.8', 000h, 000h
    ---
    > db 'VirtualBox 4.3.10', 000h
    16028c16028
    < db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 04fh
    ---
    > db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 026h


    ===


    cpu_reset: ; 0xffff0 LB 0x10
    jmp far 0f000h:0e05bh ; ea 5b e0 00 f0
    db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 026h


    ===


    cpu_reset:
    ;; This is where the CPU starts executing after a reset
    jmp far ptr post


    ;; BIOS build date
    db BIOS_BUILD_DATE
    db 0 ; padding
    ;; System model ID
    db SYS_MODEL_ID
    ;; Checksum byte
    db 0FFh


    ===


    BIOS_BUILD_DATEequ'06/23/99'
    SYS_MODEL_IDequ0FCh; PC/AT
     
  17. nerd.brazil

    nerd.brazil MDL Novice

    Feb 5, 2014
    11
    0
    0
    Ok... I'm addicted to this BIOS hacking thing... I searched a while but didn't find anything related to this:

    1) I have Lenovo Windows 8 Recovery Disc - can it be used somehow to install in VirtualBox? i.e. bypass hardware check
    2) To decompress Phoenix BIOS, I am trying to find the ancient BEDEMO.ZIP from Phoenix... anyone has it?

    Thanks!