Dump and disasm BIOS interrupt handlers -- I need help

Programming, for all ages and all languages.
Post Reply
asm112
Posts: 3
Joined: Sun May 13, 2012 10:02 am

Dump and disasm BIOS interrupt handlers -- I need help

Post by asm112 »

Hello everybody,

I'm trying to dump the Bios interrupt handlers so I can disassemble them and use the code eg. set resolution, keyboard...
and to learn how my hardware works.I have a Fujitsu Siemens V5535 laptop with Phoenix First Bios.
I have written a dos .com program in assembly (NASM) to help me do this task.The problem is that the program wont go thru the bios code, it simply freezes the virtual machine or reboots.I wont go into lengths explaining this, I will post my code here.If anyone can help please write.

P.S. Yes I have read Pinczakko's guide and I have 5 years of experience in x86 assembly

Code: Select all

[bits 16]
org 0x100

mov al,0x10                                ; number of the interrupt - int 10h
mov ah,0                         
call xint                                       ;get vector from IVT
mov dword [intaddr+1],ebx        ;store vector after the JMP so later we can do a far jump there
mov di,1                                      ;number of the interrupt - int 1h
mov bx,codex                              ;get handler's address (IP)
call setint                                    ;set the IVT
pushf                 
mov bp,sp
or word [bp],0x0100                    ;set trace flag
popf
;;;;;;;;;;;;;;;;;;;
;test code here
mov ax,0x11                      ;int 10h function 0 - set video mode 11h
;int 0x10
pushf                              ;-+                                                                --+
push cs                            ; |-  prepare the stack for IRET                        |
push here                       ;-=                                                                   + = int 10h
intaddr:                          ;                                                                        |
jmp 0x0:0x0                      ;our vector gets copied here then far jump--+ 
;;;;;;;;;;;;;;;;;;;
here:
mov ax,0x3c00
mov dx,filename
mov cx,0
int 0x21                         ;open file finction
jc err
mov bx,ax
mov ax,0x4000
mov word cx,[bcount]
mov dx,codebuffer
int 0x21                         ;write file function
jc err
endd:
xor ax,ax
int 0x20                         ;return to DOS
err:
mov ah,0x09
mov dx,errorx
int 0x21
jmp endd


filename db "int.bin",0
errorx dw 0x0d0a,"ERROR!",0x0d0a,"$"


codex:
push bp
push cx
push di
push si
push bx
push ds
push es
back_here:
mov bx,cs
mov es,bx                           ;set segment registers to this segment
mov ds,bx
mov bp,sp
mov word cx,[bp+14]                 ;get IP from stack
cmp word [first],1                  ;is this the first entry?
jne nextx                           ;if no jump, if yes continue
mov word [prevIP],cx                ;save IP as previousIP
mov cx,codebuffer                   ;get storage buffer address
mov word [cbpointer],cx             ;byte pointer to the storage buffer
mov word [first],0                  ;set to 0 so next time no first entry
jmp endc 
nextx:
xor edi,edi
xor esi,esi
mov di,[cbpointer]                  ;get our pointer
mov word bx,[prevIP]                ;get previous IP
mov word [prevIP],cx                ;save current IP as previous
sub cx,bx                           ;currentIP - previousIP=instruction size
js back                             ;if currentIP<previousIP jump ; sign flag=1
inc si                              ;to set sign flag 0
cmp cx,0x8                          ;is instruction(s) 8 byte?
jge back                            ;jump if greater
add word [bcount],cx                ;CX --> byte counter
mov si,bx                  
mov word bx,[bp+0x10]               ;get previous CS - before this handler
mov ds,bx                            
rpt:                                ;copy instruction bytes
mov byte bl,[ds:si]                 ;from BIOS code segment
mov byte [es:di],bl                 ;to our buffer
inc di
inc si
dec cx
cmp cx,0
jne rpt
mov word [es:cbpointer],di         ;save code buffer pointer
endc:
pop es
pop ds
pop bx
pop si
pop di
pop cx
or word [bp+6],0x0100              ;set trace flag
pop bp
iret                               ;return

back:
mov word [first],0x1               ;go first entry mode
jmp back_here

first      dw 0x1 ;yes
prevIP     dw 0
cbpointer  dw 0
bcount     dw 0
codebuffer db 0
User avatar
Kazinsal
Member
Member
Posts: 559
Joined: Wed Jul 13, 2011 7:38 pm
Libera.chat IRC: Kazinsal
Location: Vancouver
Contact:

Re: Dump and disasm BIOS interrupt handlers -- I need help

Post by Kazinsal »

Boot into a real MS-DOS session and use DEBUG.COM to dump the segment at F000 to a file. This most likely isn't your /entire/ BIOS though. Modern BIOSes have a lot of extra crud (SMBIOS, VBE, etc.) parked around your address space.
asm112
Posts: 3
Joined: Sun May 13, 2012 10:02 am

Re: Dump and disasm BIOS interrupt handlers -- I need help

Post by asm112 »

I already dumped my whole 2gb real mode memory and used IDA to disassemble some part of the int 10h handler, but I found that the code is not complete.There was a few "dead ends", the code unexpectedly ends - no iret or ret and most importantly no in or out functions.Also I decompressed the compressed bios rom file and and disassembled the video oprom.This metod gave me better result but it was basically a spaghetti code.I tried to trace the handler with MS-DOS DEBUG.COM and I've got some 10mb of repeating instructions.
So my idea was that I could use single stepping to execute the code ( int 10h ah=0) and since after every instruction if the trap flag is set there will be an exception int 1h.I wrote my handler so that it saves the IP of the previous instruction and resume, and then it gets the current IP of the instruction which is debugged. This way I can calculate the size of the previous debugged instruction and save it in a buffer and later write to disk.This way I could get some good usable code.
Regarding of the problem that I mentioned in my previous post, I think I will experiment with flat real mode and big real mode and of course Bochs can be of great help since it has a built in debugging facility.
Oh and Blacklight thanks for your comment :)
AbstractYouShudNow
Member
Member
Posts: 92
Joined: Tue Aug 14, 2012 8:51 am

Re: Dump and disasm BIOS interrupt handlers -- I need help

Post by AbstractYouShudNow »

So... if I've understood everything well, you want to reverse-engineer your BIOS ? That doesn't make much sense; your program should be generic, and not adapt to a specific BIOS.

Also, Phoenix Corp may have something to say about it... you know, about intellectual property and copyright :D
Because of that, their code might very well be obfuscated, so that people like you can't decompose the code they paid people to write. I'm not blaming you for that; like many osdevers, I have already disassembled existing code, but take care as you might get a lawsuit.

Whatever, the technique I suggest you is to inspect the real-mode IVT and look for common BIOS interrupts. See where they point, follow the pointer, and follow the code instruction-by-instruction, just as does the computer, but writing the disassembly of each line (instruction+arguments) you execute to a file. That will always work, because that's the way the computer does this, and the code works with the computer (or you wouldn't be running that OS :) ). However, this is way easier to do inside an emulator such as Bochs which has a debugger that disassembles as it runs.

Bear in mind also that if you are running under DOS, which might very well trap the interrupts, so you should do that before DOS starts. But trying to disassemble code from an origin that you don't know, you might encounter data, and disassemble it thinking it is code, so finding the origin of code is critical.
For a BIOS, you can take each interrupt vector that it has installed, but that way you won't get the early initialization code. To find it, know that the BIOS POST loads the BIOS and places a jump instuction at absolute address 0X00, which jumps to the start of the BIOS initialization code (that is what you want !). All you can do is hope that it has not been modified by the BIOS itself (e.g. to initialize the interrupt handlers), and try to follow it, but it's likely not to have remained there... though a try costs nothing :)

PS: I wonder how you got the compressed ROM image of a proprietary BIOS :D
User avatar
turdus
Member
Member
Posts: 496
Joined: Tue Feb 08, 2011 1:58 pm

Re: Dump and disasm BIOS interrupt handlers -- I need help

Post by turdus »

5 years of experience? Really? Have you ever heard of "xor ah, ah"?

Code: Select all

; in: al=interrupt
push 0
pop ds
xor ah, ah
shl ax, 2
mov si, ax
mov ax, [si+2]
mov si, [si]
mov ds, ax
; out: ds:si=points to ISR routine in memory
;save it to a file here (call DOS interrupt)
In case you don't know any real-mode disassembler, I suggest to download hiew for DOS.
Casm
Member
Member
Posts: 221
Joined: Sun Oct 17, 2010 2:21 pm
Location: United Kingdom

Re: Dump and disasm BIOS interrupt handlers -- I need help

Post by Casm »

You can't single step through the BIOS or MS-DOS because you are single stepping the very thing MS-DOS will be using to put stuff on the screen, or get input from the keyboard. And you will also crash the stack of a single tasking operating system, which isn't expecting to handle more than one system call at a time.

The only way you can do that is to write a debugger which does its own input and output, independently of the BIOS or MS-DOS - which is its own minature operating system, in other words. I did once write such a debugger, but that was more than twenty years ago now.
Post Reply