  | 
					
						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.
  | 
   
 
     |