|
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
REZK
Anmeldungsdatum: 28.10.2004 Beiträge: 109 Wohnort: Stuttgart
|
Verfasst am: 13.08.2006, 20:33 Titel: Probleme mit verbogenen Interrupts |
|
|
Hallo,
also, ich habe folgende Probleme:
1.) Ich habe folgendes (experimentelle) Programm:
Code: | Code Segment
Assume cs:code
Org 100h
start:
jmp weiter
hallo db "hallo$"
weiter:
mov ah,35h
mov al,21h
int 21h ; der int21 vektor steht in es:bx
mov ah,9
mov dx,offset hallo
call es:[bx]
int 20h
Code ENDS
end start
|
Das Programm macht folgendes: Es ermittelt mit der 35h Funktion des Int21 die absolute Speicherstelle des int 21 und versucht diese über call aufzurufen. Leider wird keine Message "Hallo" ausgegeben, sondern das Programm macht gar nichts und beendet sich einfach nach einer kurzen Wartezeit. Woran kann das liegen?
2.) Des weiteren habe ich noch ein Progrämmchen:
Code: |
Code Segment
Assume cs:code
Org 100h
Begin: jmp Install ;TSR installieren
int 20h
Tsr PROC FAR
Assume cs:code
jmp indosx
indos dw 0,0
hallo db "dsad$"
indosx:
mov ax, word ptr indos ;lese indos byte aus
mov es,ax
mov bx, word ptr indos+1
cmp byte ptr es:[bx],0
jne ende
mov ah,9h
mov dx, offset hallo
cli
int 21h
sti
ende:
iret
Tsr ENDP
Install PROC NEAR
Assume cs:code,ds:code
;adresse des indosflag kopieren
mov ah,34h
int 21h
mov word ptr indos,es
mov word ptr indos+1,bx
mov ah,25h ; int 13h auf die eigene Routine verbiegen
mov al,13h
mov dx,offset tsr
cli
int 21h
sti
mov dx,offset Install ;speicherresident beenden
int 27h
Install ENDP
Code ENDS
END Begin |
Es verbiegt den Int13h auf die eigene Routine.
Soweit klappt auch alles, wie vorauszusehen war, sind keine Zugriffe auf die Festplatte mehr möglich, allerdings ist das Indos Byte immer ungleich 0, das heißt, es ist momentan schon ein Interrupt aktiv, der nicht gestört werden will.
Folgende Varianten habe ich ausprobiert:
- Ausführen des Int 10 innerhalb des TSR statt des INT21: funktioniert, da es sich um einen BIOS Interrupt handelt.
- Ausführen des Int 21 innerhalb des TSR ohne Indosbyte Überprüfung: Programmcrash.
- Ausführen des Programmes mit Indosbyte Überprüfung: Indos Byte ist immer <> 0, d.h. kein Int21 ausführbar...
Wie kann ich trotzdem "irgendwie" den Int21 innerhalb des verbogenen Interrupts aufrufen? Hat die Tatsache, dass das Indosbyte immer ungleich 0 ist, etwas damit zu tun, dass ich gerade den Int13 verbogen habe? Mit dem Int9 (Tastaturhandler) funktioniert es nämlich auch nicht besser...
Vielleicht kann mir jemand weiterhelfen und vielleicht zusätzlich noch ein deutsches Tutorial über TSRs empfehlen, wobei ich Adoks Assembler Tutorial schon durchgelesen habe und auch in diversen Assembler Büchern nachgeschaut habe (in denen übrigens nicht mal was davon drin stand, dass man cli verwenden muss)
Vielen Dank im voraus,
MfG,
rezk _________________ Meine sämtlichen QB Projekte findet ihr hier |
|
Nach oben |
|
|
raph ael
Anmeldungsdatum: 12.04.2006 Beiträge: 472
|
Verfasst am: 13.08.2006, 20:57 Titel: |
|
|
BIOS- INTerrupts verbiegen, dass kann nicht gut gehen .
Weil INT 09h ja soeiner ist...
Und das INDOS-Flag sollte nicht immer ON sein.
Und du wirst wahrscheinlich nicht den INT27h, sondern den INT21h aufrufen wollen...
Steht alles hier.
SHR DX,4
Daran gedacht?
DX erhöhen?
Und ins DX soll das LETZTE BYTE DER TSR-FUNKTION REIN!
Aber bevor SHR DX,4 _________________
Zitat: | 1000 Yottabytes sind absurd. 640 Yottabytes sollten genug für jeden sein. |
|
|
Nach oben |
|
|
REZK
Anmeldungsdatum: 28.10.2004 Beiträge: 109 Wohnort: Stuttgart
|
Verfasst am: 13.08.2006, 21:33 Titel: |
|
|
Hallo raphael,
danke für die Antwort.
Zitat: | BIOS- INTerrupts verbiegen, dass kann nicht gut gehen happy .
Weil INT 09h ja soeiner ist... |
Stimmt eigentlich... Funktioniert hats aber trotzdem... wenn man den Int10h aus dem TSR heraus aufruft: wenn man eine Taste drückt, wird die eigene Routine ausgeführt.
Zitat: | Und das INDOS-Flag sollte nicht immer ON sein. |
Ja, das ist das Problem... Könnte es sein, dass da irgendein Interrupt immer stört? Oder ist die Routine zum testen des Indos Bytes falsch implementiert?
Zitat: | Und du wirst wahrscheinlich nicht den INT27h, sondern den INT21h aufrufen wollen...
Steht alles hier.
SHR DX,4
Daran gedacht?
DX erhöhen?
mit den Augen rollen
Und ins DX soll das LETZTE BYTE DER TSR-FUNKTION REIN!
Aber bevor SHR DX,4 |
Also: int 27h gibt es auch, ist eine Alternative zu int21h:31. Und das mit dem Umwandeln (shr) ist bei dem 27er sogut ich weiss nicht nötig.
Und in dx steht das Ende des TSR (oder in dem Fall der Anfang der Install Routine, ist aber ja dasselbe..)
Aber wie gesagt, das mit dem Indos Byte...
Funktioniert weder unter Freedos noch unter einer Windows ME Startdiskette...
MfG,
rezk _________________ Meine sämtlichen QB Projekte findet ihr hier |
|
Nach oben |
|
|
A.K.
Anmeldungsdatum: 02.05.2005 Beiträge: 467 Wohnort: HH
|
Verfasst am: 13.08.2006, 22:40 Titel: Re: Probleme mit verbogenen Interrupts |
|
|
REZK hat Folgendes geschrieben: |
1.) Ich habe folgendes (experimentelle) Programm:
Code: | Code Segment
Assume cs:code
Org 100h
start:
jmp weiter
hallo db "hallo$"
weiter:
mov ah,35h
mov al,21h
int 21h ; der int21 vektor steht in es:bx
mov ah,9
mov dx,offset hallo
call es:[bx]
int 20h
Code ENDS
end start
|
Das Programm macht folgendes: Es ermittelt mit der 35h Funktion des Int21 die absolute Speicherstelle des int 21 und versucht diese über call aufzurufen. Leider wird keine Message "Hallo" ausgegeben, sondern das Programm macht gar nichts und beendet sich einfach nach einer kurzen Wartezeit. Woran kann das liegen?
|
Hi,
wieso versuchst du den INT 21h an-zu-callen?
Normalerweise werden Segment und Offset bei einem INT-Aufruf automatisch auf den STACK gePUSHt (CS:IP+Call_Len).
Du benutzt ein CALL dafür, welches im Normalfall nur IP+CALL_LEN PUSHt. Richtig wäre hier ein FAR CALL, oder wird das durch deinen Assembler bereits in ein FAR CALL umgewandelt?
Die zweite Sache wäre der CALL selber.
Du hast angegeben:
CALL es:[bx]
Dort müßte es so heißen:
CALL es:bx
da du sonst als Sprungadresse den Inhalt von [es:bx] hast. Dies wären aber schon die ersten Befehle des INT 21h.
MFG A.K. _________________
http://forum.IconSoft.de
http://www.pnpbb.de - hol dir jetzt dein eigenes kostenloses Forum *NEU* |
|
Nach oben |
|
|
REZK
Anmeldungsdatum: 28.10.2004 Beiträge: 109 Wohnort: Stuttgart
|
Verfasst am: 17.08.2006, 11:06 Titel: |
|
|
Hallo,
vielen Dank A.K., jetzt läuft das Ganze.
Hier habe ich nochmal einen Quelltext:
Code: | .model tiny
.radix 16
.code
org 100
start:
mov ah,3c ;erzeuge Datei
lea dx, file
xor cx,cx
int 21h
push ax
mov ax,3513 ; ermittle Position des Int 13
int 21
mov ax,es ; es=ds
mov ds,ax
mov al,byte ptr ds:[bx]
kopiere: ;ermittle bytes im Interrupt bis iret
cmp al, byte ptr iret_1
je raus
inc al
inc word ptr zahler
jmp kopiere
raus:
mov ah,40h
pop bx
mov cx, word ptr zahler
mov dx,word ptr [int21er]
int 21
int 20h
;daten
iret_1:
iret
file db "int.txt",0
zahler dw 0
int21er dw ?
end start
|
Das Programm soll folgendes machen: Es soll eine Interrupt Routine (hier die 13er) in eine Datei schreiben, um das Ende der Routine festzustellen, wird nach einem "iret" gesucht.
Das Problem: Das Programm findet schon nach wenigen Bytes (ca. 100) ein iret bzw. Daten, die mit dem Opcode von "iret" äquivalent sind.
Da ich mir kaum vorstellen kann, dass die Interrupt Routine so kurz ist, ist wahrscheinlich ein Byte innerhalb des Interrupts, das von der Interrupt Routine als Daten (was ist der Singular von Daten ???) interpretiert wird.
Hilft es, eventuell jmp's nachzuverfolgen um diese eventuell störende Datenbereiche zu umgehen?
Ich hoffe, jemand weiss auch bei diesem problem weiter.
Danke im voraus,
MfG,
rezk _________________ Meine sämtlichen QB Projekte findet ihr hier |
|
Nach oben |
|
|
A.K.
Anmeldungsdatum: 02.05.2005 Beiträge: 467 Wohnort: HH
|
Verfasst am: 17.08.2006, 11:21 Titel: |
|
|
Hm,
das wird schwer.
Im ersten Moment ist es ja so das durch einen IRET der "Interrupt verlassen wird".
Als Äquivalent dazu kann man z.B. das END oder das RETURN aus QBasic dahernehmen.
Jetzt ist die Sache ob dieses IRET ein "echtes" oder "unechtes" ist. Also ob es einem Datenbereich angehört oder wirklich zum Programm gehört. Das hast du ja so auch schon feststellen können.
Also bleibt im Grunde genommen nichts anderes übrig als alle JMP's (auch JZ, JA....) zu verfolgen und daraus Rückschlüsse zu ziehen wo der Interrupt "zu Ende ist". CALL's gehören natürlich auch dazu.
Und dieses Auswerten ist schon eine Funktion die ein sehr kompfortabler Disassembler mitbringt aber recht aufwendig ist. Ich bin der Meinung das dies auch schon unter Reverse Engineering fällt.
Naja, im Endeffekt heißt das:
Entweder du schreibst einfach eine selbstdefinierte Anzahl von Bytes in deine Datei oder du schreibst dir ein Programm welches den Assemblercode mit den JMP's auswertet und danach die Anzahl der Bytes berechnet.
Ganz hilfreich könnte dir bei dieser Sache ein Memview-Programm sein mit dem du schon mal vor dem "Abschreiben des Interruptes" diesen durchleuchten kannst.
MFG A.K. _________________
http://forum.IconSoft.de
http://www.pnpbb.de - hol dir jetzt dein eigenes kostenloses Forum *NEU* |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|