![]() |
|
|
|
#1
|
|||
|
|||
|
How to load and then patch in 16 bit environments?
Hi,
I want to use interrupt 21h function al=1h and ah=4Bh Here is the first and second program. http://rapidshare.com/files/2394260/EXEC.rar In fact,I want to change one byte of the second program.(For example the string which is used in V.EXE to show DOS version) And at last I want to run the second program while it's changed already by the First program. So what should I do after loading the second program by putting 1 in AL. How can I access to the elements of the second program. For example data segment and code segment. Also let me know how to run the second program after changing some of its parts. Please explain it well or just show me a snippet of code. So I can understand this concept in coding. Thanks in advance. Best Regards, Zest. Here is the code: Code:
TITLE A PROGRAM TO EXECUTE ANOTHER ONE
PAGE 62,133
stseg SEGMENT STACK
BYTE 4*1024 DUP (?)
stseg ENDS
dtseg SEGMENT PUBLIC 'DATA'
PathName BYTE "C:\v.exe",0
ParamBlock WORD 0
DWORD CmdLine
DWORD Dummy,Dummy
CmdLine BYTE 4,'v.exe',0dh
Dummy BYTE 20 DUP (?)
dtseg ENDS
cdseg SEGMENT PUBLIC 'CODE'
main PROC FAR
ASSUME cs:cdseg,ds:dtseg,ss:stseg,es:dtseg
mov ax,SEG dtseg
mov ds,ax
mov es,ax
;using an algo to free some memory for the second program
mov ah,4Bh ;trying to load the second program
mov al,1
mov dx,SEG PathName
mov ds,dx
lea dx,PathName
mov bx,SEG ParamBlock
mov es,bx
lea bx,ParamBlock
int 21h
;Now the second program is loaded but not executed.
;it's time to change the data in the second one.
;But i don't know how to get access to data and code section
;of the second program.
;Wait for keypress
xor ah,ah
int 16h
mov ah,4ch
int 21h
main ENDP
cdseg ENDS
PUBLIC main
END main
|
|
#2
|
|||
|
|||
|
You are using the wrong parameter block type. Your code will generate a buffer overflow and overwrite the "CmdLine" and "Dummy" variables.
Using the correct format will give you the entry point of the loaded executable. You also must take care of how to get back when your patched program exists. |
|
#3
|
|||
|
|||
|
Hi,
Thanks for your help. I fixed this part as follows: Code:
ParamBlock LABEL WORD
WORD 0
DWORD CmdLine
DWORD DfltFCB,DfltFCB
LoadSSSP DWORD ?
LoadCSIP DWORD ?
Code:
mov bx,SEG ParamBlock ;Loading the Child Process
mov es,bx
mov bx,ParamBlock
lds dx,PgmName
mov al,01h
mov ah,4bh
int 21h
mov es,WORD PTR cs:[LoadCSIP] ;Trying to change the twentieth Byte in
mov si,20h ;the second program
mov BYTE PTR es:[si],'$'
mov ss,WORD PTR cs:[LoadSSSP] ;Trying to go to the second program and
mov sp,WORD PTR cs:[LoadSSSP]+2 ;executing it
jmp DWORD PTR cs:[LoadCSIP]
mov ah,4ch
int 21h
I have some questions to be able to understand the concept. When the second program is loaded,where is it located? Is it right after the stack segment of the first program? If it's so,I should be able to search in the memory for the bytes I want. But I need an algo to search in memory. ss of the parent program is the last segment wihch I should use and add sp to it to get the last address in the memory. After this address normally the first segment of the child program should be loaded. How can I code an algo to search in this area? Also what is the last address in the memory? I mean how far shall I do search in memory to find the desired bytes. Is there any way to use SCASB instruction to find the place in memory? In fact,let me know what should be put in ES: DI and AL and CX to be able to use SCAS instruction. Regards, Zest. |
|
#4
|
|||
|
|||
|
How does it "not work" ?
From the code you posted above, I would most likely guess that your "loader" has not resized his own memory and will be using all memory up to 640 KB which means there is simply no room for the other program to be loaded. Even if you fix this, you don't set up DS and ES before jumping to CS:IP. And how do you expect to get back to your "mov ah,4ch / int 21h" code after the jump to the other program? It's not like you would be calling something which would return with a "retf". And how would you like to "SCASB" yourself to the location you want to patch? If you go for INT 21/AX=4B01, you will have the location you want to patch relative to CS:IP of the loaded program. If you're going with INT21/AX=4B00, DOS will load, execute and unload the program without giving you even a chance of patching something. You have to understand that DOS had no constant memory management, no support for multi tasking and no support for IPC (expect the 4F0 area). Have you ever seen any DOS memory patchers? They all hooked some interrupt vectors and watched the call address to match some specific values. |
![]() |
|
|