我有一个程序可以改变1Ch int程序并将自己加载为住宅。它有.EXE结构(我知道.COM更好),但我需要.EXE。我有程序的东西显示MCB阻止信息。安装新的1Ch int程序后,我可以看到出现了一个新的MCB块,它与我的住宅程序有关。但是在我试图释放内存(在我看来卸载居民)之后,与住宅计划相关的MCB块仍然存在。我的.EXE结构如下所示:stack segment-> code segment(这里也有一些数据)。我在加载之前保存了PSP地址,当我尝试卸载程序时,我得到了stadart 1Ch int程序,然后我在ES中输入了保存的PSP地址,然后调用了int 21h的49h。 那么我怎样才能完全卸载.EXE住宅计划?
UPD:我做了一些编码并且有代码可以工作,但是当我试图在AFDPRO中调试它之后,在第一次启动驻留时加载精细包子当我试图在调试器中加载其他程序时,就像那样显示MCB块,调试器崩溃。这是一个代码: ASTACK segment stack
dw 100h dup('*')
END_OF_STACK_MARK = $
ASTACK ends
ACODE segment
assume CS: ACODE, DS: ACODE, SS: ASTACK
NEW_INT_PROC proc far
push DS ;Saving registers
push ES
push AX
push BX
push CX
push DX
push SI
push DI
mov AX, ACODE ;Setting CODE seg to ds to
mov DS, AX ;correctly accessing residential data
xor AX, AX
cmp val_COUNTER, 10
je CLEAR_COUNTER
mov AL, val_COUNTER
add AL, '0'
inc val_COUNTER
call DIRECT_PRINT
jmp EXIT_RES
CLEAR_COUNTER:
mov val_COUNTER, 0
EXIT_RES:
pop DI ;Recovering registers
pop SI
pop DX
pop CX
pop BX
pop AX
pop ES
pop DS
mov AL, 20h
out 20h, AL
iret
NEW_INT_PROC endp
DIRECT_PRINT proc near
push AX
push BX
push CX
push DX
push SP
push BP
push SI
push DI
;Getting current cursor position
mov AH, 03h
mov BH, 00h
int 10h
push DX;Saving current row and collumn of cursor position
;Settin new cursor position
mov AH, 02h
mov BH, 00h
mov DX, 0000h
int 10h
;Print number from AL
mov AH, 09h
mov BH, 0
;mov BL, 153
mov CX, 1
int 10h
;Recovering cursor position
mov AH, 02h
mov BH, 00h
pop DX;Recoveing initial cursor position
int 10h
pop DI
pop SI
pop BP
pop SP
pop DX
pop CX
pop BX
pop AX
ret
DIRECT_PRINT endp
str_MOD db 'StdMod$' ;\ Residential data (ResMod - if residential program, StdMod - if not residential program)
val_COUNTER db 0 ; |
val_RES_PSP_ADDR dw 0 ; | PSP address of residential programm
val_OLD_INT_PROC_ADDR dd 0 ;/ Old int 1Ch address
NEW_INT_PROC_MEM_MARK = $
PRNT_MARKED_STRING proc near
;Print string with end of string mark
;String offset must be in DX
push AX
mov AH, 09h
int 21h
pop AX
ret
PRNT_MARKED_STRING endp
LOAD_RESIDENT proc near
push AX
push BX
push DX
mov [str_MOD], 'R'
mov [str_MOD + 1], 'e'
mov [str_MOD + 2], 's'
mov [val_RES_PSP_ADDR], ES ;Save PSP address to realise memory later
push ES
mov AX, 351Ch ;Getting CS:IP of standart interruption procedure
int 21h
mov word ptr [val_OLD_INT_PROC_ADDR], BX ;IP of standart interruption procedure saved
mov word ptr [val_OLD_INT_PROC_ADDR + 2], ES ;CS of standart interruption procedure saved
pop ES
push DS
mov DX, offset NEW_INT_PROC ;Installing new interruption on 1Ch
mov AX, seg NEW_INT_PROC
mov DS, AX
mov AX, 251Ch
int 21h
pop DS
pop DX
pop BX
pop AX
ret
LOAD_RESIDENT endp
FREE_RESIDENT proc near
push AX
push BX
push DX
push ES
mov AX, 351Ch
int 21h
mov AX, word ptr ES:[val_OLD_INT_PROC_ADDR]
mov word ptr [val_OLD_INT_PROC_ADDR], AX
mov BX, word ptr ES:[val_OLD_INT_PROC_ADDR + 2]
mov word ptr [val_OLD_INT_PROC_ADDR + 2], BX
mov ES, ES:[val_RES_PSP_ADDR]
push ES
mov ES, ES:2Ch
mov AH, 49h
int 21h
pop ES
mov AH, 49h
int 21h
pop ES
cli ;Recovering standart interruption
push DS
mov DX, word ptr [val_OLD_INT_PROC_ADDR]
mov AX, word ptr [val_OLD_INT_PROC_ADDR + 2]
mov DS, AX
mov AX, 251Ch
int 21h
pop DS
sti
pop DX
pop BX
pop AX
ret
FREE_RESIDENT endp
IS_RES_RUNNING proc near
push ES
mov AX, 351Ch
int 21h
cmp ES:[str_MOD], 'R'
jne EXIT_RES_NOT_RUNNING
cmp ES:[str_MOD+1], 'e'
jne EXIT_RES_NOT_RUNNING
cmp ES:[str_MOD+2], 's'
jne EXIT_RES_NOT_RUNNING
cmp ES:[str_MOD+3], 'M'
jne EXIT_RES_NOT_RUNNING
cmp ES:[str_MOD+4], 'o'
jne EXIT_RES_NOT_RUNNING
cmp ES:[str_MOD+5], 'd'
jne EXIT_RES_NOT_RUNNING
mov [val_RES_RUNNING], 1
EXIT_RES_NOT_RUNNING:
pop ES
ret
IS_RES_RUNNING endp
USER_UNLOAD proc near
push ES
push AX
push BX
mov AH, 62h
int 21h
mov ES, BX
cmp byte ptr ES:[80h], 04h
jne EXIT_USR_INLOAD
cmp byte ptr ES:[82h], '/'
jne EXIT_USR_INLOAD
cmp byte ptr ES:[83h], 'u'
jne EXIT_USR_INLOAD
cmp byte ptr ES:[84h], 'n'
jne EXIT_USR_INLOAD
mov [val_RES_USR_UNLOAD], 1
EXIT_USR_INLOAD:
pop BX
pop AX
pop ES
ret
USER_UNLOAD endp
str_RES_LOADED db 'Residential program has been loaded', 10, 13, '$'
str_RES_RUNNING db 'Residential program is running', 10, 13, '$'
str_RES_NOT_RUNNING db 'Residential program is not running', 10, 13, '$'
str_RES_UNLOADED db 'Residential program has been unloaded', 10, 13, '$'
val_RES_RUNNING db 0
val_RES_USR_UNLOAD db 0
MAIN proc far
sub AX, AX
mov AX, ACODE
mov DS, AX
call IS_RES_RUNNING
cmp val_RES_RUNNING, 1
je FREE_RESIDENT_PROG
mov DX, offset str_RES_NOT_RUNNING
call PRNT_MARKED_STRING
mov DX, offset str_RES_LOADED
call PRNT_MARKED_STRING
call LOAD_RESIDENT
mov DX, offset NEW_INT_PROC_MEM_MARK
add DX, offset END_OF_STACK_MARK
add DX, 10Fh
mov CL, 4
shr DX, CL
mov AX, 3100h
int 21h
FREE_RESIDENT_PROG:
mov DX, offset str_RES_RUNNING
call PRNT_MARKED_STRING
call USER_UNLOAD
cmp val_RES_USR_UNLOAD, 1
jne EXIT
mov DX, offset str_RES_UNLOADED
call PRNT_MARKED_STRING
call FREE_RESIDENT
EXIT:
mov AX, 4C00h
int 21h
MAIN endp
ACODE ends
end MAIN
答案 0 :(得分:0)
在中断表中设置int 1Ch之前(段:0偏移:1Ch * 4),程序应该在程序写入例程的地址之前保存存储在此偏移处的dword。要卸载,您必须恢复该dword。这将恢复旧的中断向量