'>>> Page 2 of WIN95SPY.BAS begins here.
incr all_int21(status) 'Variablenzugriff ueber DS moeglich
if v86 then incr v86_int21(status)
CHAIN_vector=old_vec1 'ersetzt die C-Funktion
! call near pop_and_chain ; "_chain_intr(old_vector)"
'----------------------------------------------------------------------------
INT_serv2: 'ISR fuer 2. Interrupt (INT 2F)
! CALL near push_for_chain
! CALL near READ_PB_regs
! mov k,ax
! mov i,ah
if win then 'die verschiedenen Stadien von Windows registrieren
if k = %W_INIT_CODE then
status=%W_INIT
elseif k = %W_READY_CODE then
status=%W_READY: t2 = count_t 't2 = WIN start
elseif k = %W_EXIT_CODE then
status=%W_EXIT : t3 = count_t 't3 = WIN endet
elseif k = %W_DONE_CODE then
status=%W_DONE
end if
if status = %W_READY then
incr int2F(i)
incr iopl_int2F(iopl)
incr vm_int2F(vmid)
end if
else
incr int2F(i)
end if
incr all_int2F(status)
if v86 then incr v86_int2F(status)
CHAIN_vector=old_vec2
! call near pop_and_chain
'---------------------------------------------------------------------------
'Der primaere Timer-Interrupt &H08 (Hardware-IRQ0 ueber den 8259-Controller)
'tickt IMMER GENAU alle 55 Millisekunden. - Der nachgehaengte Timer-Interrupt
'&H1C (Software INT) ist unkritischer,tickt aber UNGENAU, wenn in der
'&H1C-ISR zu viel Zeit verbraucht wird !!!
timer_int: 'Timer tick
! pushf ;diese 2 Zeilen simulieren einen INT!
! call dword ptr old.timer.vector ;ZUERST die alte &H08-ISR bedienen !!!
! CALL near push_ALL ;regs retten (Aufrufer-STACK)
! CALL near READ_PB_regs ;PB Regs lesen
incr count_t 'Variablenzugriff ueber DS moeglich
! CALL near pop_ALL ;regs restaurieren (Aufrufer-STACK)
! iret
'---------------------------------------------------------------------------
push_for_chain: 'muss IMMER paarweise mit "pop_and_chain" auftreten!
' hier: zuerst return_address, dann ax
! push bx
! push cx
! push dx
! push es
! push ds
! push si
! push di
! push bp
! mov bp,sp ;Bezugs-BP
! mov bx,[bp+16] ;bx = return addresse holen
! mov [bp+16],ax ;jetzt ax dorthin
! push bx ;<-- return addresse
! retn
pop_and_chain: 'DS muss unbedingt noch intakt sein, alle anderen nicht
! pop ax ;return addresse weg
! mov bp,sp ;Bezugs-BP restaurieren
! mov ax,[bp+16] ;ax + bx restaurieren und
! mov bx,[bp+14] ; 2 Plaetze frei machen
! mov cx,CHAIN_vector[00]
! mov [bp+14],cx ;chain Addresse LO word (offset)
! mov cx,CHAIN_vector[02]
! mov [bp+16],cx ;chain Addresse HI word (segment)
! pop bp ;restl. Register restaurieren
! pop di
! pop si
! pop ds
! pop es
! pop dx
! pop cx
! cli ;wird von der chain routine erwartet
! retf ;Absprung zur chain routine
'---------------------------------------------------------------------------
push_ALL: 'PUSH_ALL und POP_ALL muessen IMMER paarweise verwendet werden!
' hier: return Addresse BLEIBT auf dem Stack!!
! push ax
! push bx
! push cx
! push dx
! push es
! push ds
! push si
! push di
! push bp
! mov bp,sp
! mov ax,[bp+18] ;ax=RETURN address
! push ax ;<== RETURN address
! retn
pop_ALL:
! mov bp,sp
! mov ax,[bp] ;ax=RETURN address
! mov [bp+20],ax ;first TO this location
! pop bp ;THEN throw away
! pop bp ;pop all registers
! pop di
! pop si
! pop ds
! pop es
! pop dx
! pop cx
! pop bx
! pop ax
! retn
'---------------------------------------------------------------------------
SAVE_PB_regs: 'wird NUR vor dem SHELL Befehl aufgerufen!
! mov PB.regs[00],si
! mov PB.regs[02],di
! mov PB.regs[04],bp
! mov PB.regs[06],ds
! retn
READ_PB_regs: 'ss/sp darf hier NICHT gelesen werden (wegen retn)
! mov ds, PB.regs[06] ;PB-Regs
! mov bp, PB.regs[04]
! mov di, PB.regs[02]
! mov si, PB.regs[00]
! retn
prepare_old_timvec:
! mov ax, old_vec3[00] ;vector von DS nach CS umspeichern
! mov old.timer.vector, ax ;offset
! mov ax, old_vec3[02]
! mov old.timer.vector[02], ax ;segment
! retn
'-------------------- Datenbereich im Codesegment: --------------------------
old.timer.vector:
! dd 0
PB.regs:
! dd 0 ;si,di
! dd 0 ;bp,ds
'******************* Ende der Inline-ASM (NEAR) Routinen *******************
FUNCTION win_version () AS STRING
DIM major AS INTEGER, minor AS INTEGER
! mov ax, &h1600
! INT &h2F
! mov major, al
! mov minor, ah
IF major=0 OR major=&H80 THEN
win_version=" keine"
ELSEIF major=1 OR major=&HFF THEN
win_version=" WIN/386 V2.x"
ELSE
win_version$ = STR$(major) + "." + LTRIM$(STR$(minor))
END IF
END FUNCTION
FUNCTION vmid () AS INTEGER 'liest Virtual Machine ID (unter WIN)
! mov ax, &h1683
! INT &h2f
! mov FUNCTION[00], bx
END FUNCTION
function iopl () as integer 'liest IOPL Status (unter WIN)
! pushf
! pop ax
! and ax,3
! mov FUNCTION[00],ax
end function
FUNCTION v86 () AS INTEGER 'liest PE bit (DOS oder WIN/DOS-Fenster)
! dw &H010F ;0F01E0 = "smsw ax" (store machine status word)
! db &HE0
! AND ax,1
! mov FUNCTION[00],ax
END FUNCTION
SUB CmdLine (argc AS INTEGER, argv() AS STRING, maxargs AS INTEGER)
' Aufteilung der Kommandozeile in Einzelelemente (Argumente)
' argv(0) - immer Programmpfad + Name
' argc - Anzahl zusaetzlicher Argumente ohne argv(0) (ist in C anders!!)
' argv() - Array zur Rueckgabe der Argumente
' maxargs - Maximal erlaubte Anzahl Argumente, wegen DIM argv(0:maxargs)
DIM EnvSeg AS WORD, EnvOfs AS WORD
DIM Char AS BYTE, Temp AS STRING, C AS STRING
DIM i AS INTEGER, l AS INTEGER, in_arg AS INTEGER
! push DS ;Teil 1 stammt aus der DOSUNIT von PB
! mov AX, &H6200 ;PSP Addresse
! int &H21 ;von DOS erfragen
! mov DS, BX ;PSP segment in DS
! mov AX, DS:[&H2C] ;environment Segment in AX
! mov EnvSeg, AX ;in EnvSeg variable
! pop DS ;restore DS
DEF SEG = EnvSeg: EnvOfs = 0
WHILE PEEKI(EnvOfs) > 0 '2 Null-bytes suchen
INCR EnvOfs
WEND
INCR EnvOfs, 4 'das ist der Beginn des Strings
Char = PEEK(EnvOfs)
WHILE Char > 0 'bis zum Trennzeicehne CHR$(0)
Temp = Temp + CHR$(Char) 'den ges. String lesen
INCR EnvOfs
Char = PEEK(EnvOfs)
WEND
DEF SEG
argv(0) = Temp 'Ergebn. z.B.: "C:\PATH\MYPROG.EXE"
argc = 0 'Teil 2: selbst gemacht
in_arg = %FALSE ' (DOSUNIT von PB zu umstaendlich)
Temp = COMMAND$ 'Kommandozeile uebernehmen
L = LEN(Temp)
FOR I = 1 TO L 'Jedes Zeichen pruefen
C = MID$(Temp, I, 1)
IF C " " AND C CHR$(9) THEN 'Space oder Tab = Trennzeichen?
IF NOT in_arg THEN 'neues Argument beginnt
IF argc = maxargs THEN EXIT FOR
argc = argc + 1
in_arg = %TRUE
END IF
argv(argc) = argv(argc) + C 'Zeichen uebernehmen
ELSE
in_arg = %FALSE
END IF
NEXT I
' argc=argc+1 'so waer's C-konform
END SUB
FUNCTION dos_getvect (BYVAL intr AS BYTE) AS DWORD
! mov ah, &H35 ;DOS: GET INTERRUPT vector
! mov al, intr ; al = INTERRUPT number
! INT &H21
! mov function[02], es ;ES:BX = INTERRUPT vector
! mov function[00], bx
END FUNCTION
SUB dos_setvect (BYVAL intr AS BYTE, BYVAL vectorptr AS DWORD)
! push ds
! mov ah, &H25 ;DOS: set INTERRUPT vector
! mov al, intr ; al = INTERRUPT number
! mov ds, vectorptr[02] ;DS:DX = INTERRUPT vector
! mov dx, vectorptr[00]
! INT &H21
! pop ds
END SUB
function hex2 (i as integer) as string
dim x as string
x = hex$(i)
if len(x)=1 then x="0"+x
hex2=x
end function
function screen_redir() as integer
! mov ax, &H4400 ;IOCTL - Geraeteauskunft holen
! mov bx, 1 ;handle 1 = standard Output STDOUT
! int &H21
! not dx ;alle bits umdrehen, dann gilt:
! and dx, &H80 ;bit 7 = 0 --> Zeichentreiber (Screen)
! mov function[00], dx ;bit 7 = 1 --> Blocktreiber (File)
end function
'>>> Page 2 of WIN95SPY.BAS ends here. Last page.
--- CrossPoint v3.11 R
---------------
* Origin: Fido Point of Disillusion (2:2480/13.34)
|