Code eines INT im Debugger betrachten...
-
Hallo nochmal,
das BIOS stellt ja eine Menge Funktionen bereit.
Kann man den Code in einen Buffer einer laufenden .com Datei kopieren, eine neue Datei erzeugen (Int 21h), den Code dort reinschreiben und dann im Debugger ansehen?
Ich habe es versucht aber das sieht aus als ob nur Byte Variablen definiert wurden.
db 0F7h
db 040h
db 021h
usw. usf.hier mal mein Vorgehen:
xor ax, ax
mov ds, ax
mov si, 13h * 4 ;SI zeigt auf das 4-Byte große Segment:Offset Paar
mov ax, {si] ;2 Byte kopieren (Offset)
mov i_offset, ax
mov ax, [si + 2] ;nochmal 2 Byte kopieren für das Segment
mov i_segment, axes:di hab ich auf einen Buffer eingestellt (4096 Byte)
mov ax, i_segment ;Segment und Offset des Int nach DS:SI
mov ds, ax
mov ax, i_offset
mov si, axmov cx, 4096 ;4096 Byte kopieren nach ES:DI
rep movsbsomit ist der Code im Buffer (ich denke 4096 Byte sollten dafür reichen)
Mit dem Int21 habe ich eine neue Datei erstellt und den Buffer dort reingeschrieben. Im Debugger sind aber keine MOV oder POP Befehle enthalten..
Hab ich was vergessen?
Nicky
-
In welchem OS startest du denn deine Versuche?
In der NTVDM (Windows NT VM fuer DOS) oder selbst in Win9X stehen bei den Interruptvectoren recht lustige Dinge, bzw. einfach Quatsch und die Aufrufe werden (z.B. ueber Exceptions) abgefangen.Wenn du dir den echten BIOS-Code hinter diesen Aufrufen anschauen willst, wuerde ich eine Debug-Session in einem echten DOS (am besten auch echter Real Mode - d.h. kein emm386) vorschlagen, oder mal ein BIOS-Image mit Hilfe einer VM wie Bochs zerlegen.
-
supernicky schrieb:
xor ax, ax
mov ds, ax
(...)
mov i_offset, axDas ist der Fehler. Wenn Du etwas in eine Variable schreibst, dann muss auch DS dorthin zeigen. In diesem Fall zeigt DS auf die Interrupttabelle und nicht auf das Programmsegment.
Hier ein Beispiel, wie es funktioniert. Ich habe mich dabei soweit wie möglich an Deine Vorgaben gehalten (es gibt bessere Möglichkeiten):
; Name: NICKY.ASM ; Assemblieren: tasmx.exe NICKY.ASM ; Linken: tlink.exe /t NICKY.OBJ .MODEL TINY .CODE ORG 0100h Start: xor ax, ax mov ds, ax mov si, 13h * 4 ;SI zeigt auf das 4-Byte große Segment:Offset Paar mov ax, [si] ;2 Byte kopieren (Offset) mov cs:i_offset, ax mov ax, [si + 2] ;nochmal 2 Byte kopieren für das Segment mov cs:i_segment, ax ; ES:DI = Freier Speicherbereich (Page-aligned) hinter dem Programm mov ax, cs mov es, ax mov di, OFFSET ziel add di, 1000h ; Alignment bei der nächsten Page and di, 0F000h mov cs:ziel, di mov ax, cs:i_segment ;Segment und Offset des Int nach DS:SI mov ds, ax mov bx, cs:i_offset mov si, bx mov cx, 4096 ;4096 Byte kopieren nach ES:DI rep movsb ; Neue Datei erstellen und öffnen mov ax, cs mov ds, ax mov dx, OFFSET datei xor cx, cx mov ah, 3Ch int 21h mov handle, ax ; Datei schreiben mov bx, handle mov cx, 4096 mov dx, ziel mov ah, 40h int 21h ; Datei schließen mov bx, handle mov ah, 3Eh int 21h ; Exit 0 mov ax, 4C00h int 21h datei db "INT13.COM",0 handle dw ? i_offset dw ? i_segment dw ? ziel dw ? ; muss die allerletzte Variable sein ENDS END Start
viele grüße
ralph
-
Nobuo T schrieb:
In welchem OS startest du denn deine Versuche?
In der NTVDM (Windows NT VM fuer DOS) oder selbst in Win9X stehen bei den Interruptvectoren recht lustige Dinge, bzw. einfach Quatsch und die Aufrufe werden (z.B. ueber Exceptions) abgefangen.Wenn du dir den echten BIOS-Code hinter diesen Aufrufen anschauen willst, wuerde ich eine Debug-Session in einem echten DOS (am besten auch echter Real Mode - d.h. kein emm386) vorschlagen, oder mal ein BIOS-Image mit Hilfe einer VM wie Bochs zerlegen.
Hallo Nobuo,
ich habe Virtual PC laufen und darin mein erstes OS Win98SE installiert.
Einen laten Laptop habe ich auch noch wo ich es versuchen könnte, dann fällt die VM weg. Jedoch habe ich bei keinem PC ein Disk-Laufwerk dran, sodass ich die 300Byte Datei nur über CD hin- und her schieben könnte.Vielleicht finde ich noch einen Netzwerktreiber für mein Win98, dann versuch ich es mal.
Danke
Nicky
-
rkhb schrieb:
supernicky schrieb:
xor ax, ax
mov ds, ax
(...)
mov i_offset, axDas ist der Fehler. Wenn Du etwas in eine Variable schreibst, dann muss auch DS dorthin zeigen. In diesem Fall zeigt DS auf die Interrupttabelle und nicht auf das Programmsegment.
Hallo,
das leuchtet ein.. anstatt cs kann ich ja auch es nutzen.
Also DS:SI auf die Interrupt Einträge und ES:DI auf meine zwei Variablen..gleich nochmal ans Werk
Danke schön..
Nicky
-
supernicky schrieb:
rkhb schrieb:
supernicky schrieb:
xor ax, ax
mov ds, ax
(...)
mov i_offset, axDas ist der Fehler. Wenn Du etwas in eine Variable schreibst, dann muss auch DS dorthin zeigen. In diesem Fall zeigt DS auf die Interrupttabelle und nicht auf das Programmsegment.
Hallo,
das leuchtet ein.. anstatt cs kann ich ja auch es nutzen.
Also DS:SI auf die Interrupt Einträge und ES:DI auf meine zwei Variablen..gleich nochmal ans Werk
Danke schön..
Nicky
Hallo nochmal,
habe den Fehler gefunden...
am Anfang der "Datei" steht ein FAR Jump.
Segemet und Offset habe ich in den Assembler eingetragen als Festwert und dann kam auch das richtige raus.
Leider springt er auch hier oefters mal in andere Segmentesodass ich mir vielleicht diese auch noch holen müsste.
Jedenfalls geht es nun.
Nochmals Danke
Nicky