2015-04-03 23 views
0

我有一個程序可以更改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 
+0

做一個web搜索卸載tsr。在EXE的情況下,當EXE第一次運行時,您需要將PSP存儲在EXE中的某個局部變量中,然後使用它(設置ES)來釋放內存。 – rcgldr 2015-04-06 16:46:37

+0

是的,我也是。但有一些錯誤,我喜歡不正確的退出到DOS。 – GALIAF95 2015-04-06 19:56:32

回答

0

之前中斷表設置INT代上(段:偏移0:1通道* 4),你的程序應該保存在該DWORD存儲在這個偏移量之前,你的程序寫入你那裏的日常工作地址。要卸載,您必須恢復該雙字。這將恢復舊的中斷向量

+0

是的。我這樣做。但是,程序仍然留在內存中。這是約21小時49小時或4Ah的東西,但我不知道如何正確使用它們。 – GALIAF95 2015-04-03 13:28:09

+0

執行「卸載TSR」的網頁搜索。我找到了一些鏈接,不確定哪些鏈接包含了你需要的所有代碼。一個是「C」示例,使用「int」調用函數,在執行「int」指令之前將傳遞的參數放入寄存器中。 – rcgldr 2015-04-06 21:01:17

+0

我已經找到了方法來做到這一點。我只需要清理我的程序的環境。 – GALIAF95 2015-04-06 21:15:39