如何从内存中卸载.EXE住宅程序

时间:2015-04-03 10:29:33

标签: assembly masm

我有一个程序可以改变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

1 个答案:

答案 0 :(得分:0)

在中断表中设置int 1Ch之前(段:0偏移:1Ch * 4),程序应该在程序写入例程的地址之前保存存储在此偏移处的dword。要卸载,您必须恢复该dword。这将恢复旧的中断向量