我有一個程序可以更改1Ch int過程並將其自身加載爲住宅。它有.EXE結構(我知道.COM是可取的),但我需要.EXE。我有程序,顯示MCB塊信息。在安裝新的1Ch int程序後,我可以看到出現了一個新的MCB塊,它與我的住宅計劃有關。但在我試圖釋放記憶(在我看來是卸載居民)後,與住宅計劃有關的MCB塊仍然存在。我的.EXE結構看起來像這樣:stack segment-> code segment(這裏也有一些數據)。並且我在加載之前保存PSP地址,當我嘗試卸載程序時,我得到stadart 1Ch int程序返回一個put在PS中保存的PSP地址,然後我調用int 21h的49h。 那麼我該如何完全卸載.EXE住宅計劃?如何從內存中卸載.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
做一個web搜索卸載tsr。在EXE的情況下,當EXE第一次運行時,您需要將PSP存儲在EXE中的某個局部變量中,然後使用它(設置ES)來釋放內存。 – rcgldr 2015-04-06 16:46:37
是的,我也是。但有一些錯誤,我喜歡不正確的退出到DOS。 – GALIAF95 2015-04-06 19:56:32