[RESOLVED] NASM - Trying to write a TSR->
I decided to write a TSR for MS-DOS (specifically DOSBox) Why? Because I am curious as to what all that software writes to memory. DOSBox has a debugger version but I don't like it. Anyway:
Code:
; Memory Dumper TSR v1.00 - by: Peter Swinkels, ***2021***
; This terminate and stay resident program dumps all conventional memory to a file upon request.
ORG 0x100
Main:
MOV AH, 0x35 ; Retrieves the keyboard interrupt vector.
MOV AL, 0x16 ;
INT 0x21 ;
MOV AX, ES ; Redirects the retrieved keyboard interrupt vector.
MOV DS, AX ;
MOV DX, BX ;
MOV AH, 0x25 ;
MOV AL, 0xFF ;
INT 0x21 ;
MOV AX, CS ; Sets the original keyboard vector to this program's memory dump function.
MOV DS, AX ;
MOV DX, MemoryDumper ;
MOV AH, 0x25 ;
MOV AL, 0x16 ;
INT 0x21 ;
MOV AH, 0x31 ; Terminates and stays resident.
INT 0x21 ;
MemoryDumper:
PUSHA ; Saves all registers.
MOV AH, 0x01 ; Skips the memory dump unless the F12 key has been pressed.
INT 0xFF ;
CMP AX, 0x0086 ;
JNE Done ;
MOV AX, CS
SUB AX, 0x0100
MOV DS, AX
MOV AH, 0x3C ; Creates the output file.
MOV CX, 0x00 ;
MOV DX, OutputFile ;
INT 0x21 ;
JC Done ;
MOV AH, 0x3D ; Opens the output file for writing.
MOV AL, 0x01 ;
MOV DX, OutputFile ;
INT 0x21 ;
JC Done ;
MOV BX, AX ; Retrieves the filehandle.
MOV AX, DS ; Saves the current data segment.
MOV ES, AX ;
MOV WORD [MemorySegment], 0x0000 ; Sets the first memory block.
Dump:
ES ; Sets the memory block to be written to the output file.
MOV AX, [MemorySegment] ;
MOV DS, AX ;
MOV AH, 0x40 ; Writes the memory block to the output file.
MOV CX, 0xFFFF ;
MOV DX, 0x0000 ;
INT 0x21 ;
JC Done ;
ES ; Checks whether the last memory block has been reached.
MOV AX, [MemorySegment] ;
CMP AX, 0xF000 ;
JAE DumpFinished ;
ADD AX, 0x1000 ; Moves to the next memory block.
ES ;
MOV [MemorySegment], AX ;
JMP Dump
DumpFinished:
MOV AH, 0x3E ; Closes the output file.
INT 21h ;
JC Done ;
Done:
POPA ; Restores all registers.
INT 0xFF ; Calls the redirected keyboard interrupt.
IRET ; Returns.
OutputFile DB "MemDump.dat", 0x00
MemorySegment DW 0x0000
It appears to set up the hook fine and I know the part that writes the memory to a file should work because I tested it separately. Does anyone see any obvious flaw? It could be any small thing I overlooked. No file is ever created.
EDIT:
I am using the Netwide Assembler (NASM)
Re: Trying to write a TSR->
I don't know what assembler you are using, but in TASM or MASM you should use offset keyword:
Code:
MOV DX, offset MemoryDumper
or LEA (load effective address) instruction:
Code:
LEA DX, MemoryDumper
Re: NASM - Trying to write a TSR->
Hi, thank you for pointing that out. In NASM (which I forgot to mention as the one I am using) "MOV DX, MemoryDumper" should work. However I will look into using the LEA opcode.
Re: NASM - Trying to write a TSR->
INT 21h, AH=31h function number expects resident size in paragraphs in DX register but it's currently undefined (probably zeroed) after the previous INT 21h call.
cheers,
</wqw>
Re: NASM - Trying to write a TSR->
Hi wqweto, I will look into that.
After some testing:
1. I suspect there may be an issue with the way the DS (data segment) register is set while my code is being called as though it were an interrupt. I can't just set DS to equal CS (code segment) because of the ORG 0x0100 directive which is necessary because MS-DOS expects the data segment to be 0x10 paragraphs (of 0x10 bytes) ahead of CS.
2. Or the way I am calling the keyboard interrupt and checking for a keystroke is faulty.
Re: NASM - Trying to write a TSR->
Start simply: write somewhere on the screen the keystroke received, e.g. put it on first byte of video memory as it is just text mode (not sure at the moment if it was segment at 0b800h or something different). This way you will see if your keyboard hook works fine. No checks for the key, no memory dump, just print the ascii code.
Then you can move to next step.
Re: NASM - Trying to write a TSR->
If you want to play more with DOS, Ralf Brown's Interrupt List is a must have: http://www.cs.cmu.edu/~ralf/files.html
Re: NASM - Trying to write a TSR->
EDIT: The code posted here has been updated.
Looking at this YouTube video: https://www.youtube.com/watch?v=PQXNpPul5oo&t=1960s - I wrote the following:
Code:
; A TSR for MS-DOS - By: Peter Swinkels, ***2021***
; Retrieves interrupt 0x08's vector.
CLI
MOV AH, 0x35
MOV AL, 0x08
INT 0x21
; Places the retrieved vector at another interrupt.
MOV DX, BX
PUSH ES
POP DS
MOV AH, 0x25
MOV AL, 0xC8
INT 0x21
; Places this TSR at interrupt 0x08.
PUSH CS
POP DS
MOV DX, TSR
MOV AH, 0x25
MOV AL, 0x08
INT 0x21
; Terminates and stays resident.
MOV AH, 0x31
MOV AL, 0x00
MOV DX, 0x00FF
INT 0x21
TSR:
; Disables hardware interrupts.
CLI
; Saves the registers.
PUSHA
PUSH DS
; Disables Num Lock.
MOV AX, 0x40
MOV DS, AX
MOV BX, 0x17
MOV AX, [BX]
AND AX, 0x6F
MOV [BX], AX
; Restores the registers.
POP DS
POPA
; Calls the redirected interrupt.
INT 0xC8
; Sends an End-Of Interrupt signal to the 8259 interrupt controller.
PUSH AX
MOV AL, 0x20
OUT 0x20, AL
POP AX
; Returns.
STI
IRET
The program runs, and happily returns to the prompt, but nothing happens! I suspect DOSBox might not support TSR's written in this fashion. Anyone?
Re: NASM - Trying to write a TSR->
In "Places this TSR at interrupt 0x08" section it has MOV AL, 0xC8 but probably should be MOV AL, 0x08
cheers,
</wqw>
Re: NASM - Trying to write a TSR->
Quote:
Originally Posted by
wqweto
In "Places this TSR at interrupt 0x08" section it has MOV AL, 0xC8 but probably should be MOV AL, 0x08
cheers,
</wqw>
maybe the same thing in the blocks "; Places the retrieved vector at another interrupt." and
"; Calls the redirected interrupt."
Re: NASM - Trying to write a TSR->
@wqweto: I fixed to the typo. 0xC8 is now 0x08. This has made some difference. The program now freezes DOSBox... Sigh. Any ideas?
Re: NASM - Trying to write a TSR->
Okay, I made a few changes and decided to try to have my TSR display a character instead of modifying the Num Lock status. Code:
Code:
; A TSR for MS-DOS - By: Peter Swinkels, ***2021***
ORG 0x0100
; Retrieves interrupt 0x08's vector.
CLI
MOV AH, 0x35
MOV AL, 0x08
INT 0x21
; Places the retrieved vector at another interrupt.
MOV DX, BX
PUSH ES
POP DS
MOV AH, 0x25
MOV AL, 0xC8
INT 0x21
; Places this TSR at interrupt 0x08.
PUSH CS
POP DS
MOV DX, TSR
MOV AH, 0x25
MOV AL, 0x08
INT 0x21
; Terminates and stays resident.
MOV AH, 0x31
MOV AL, 0x00
MOV DX, 0x00FF
INT 0x21
TSR:
; Disables hardware interrupts.
CLI
; Saves the registers.
PUSHA
PUSH DS
; Displays a character.
MOV DL, 0x21
MOV AH, 0x02
INT 0x21
; Restores the registers.
POP DS
POPA
; Calls the redirected interrupt.
INT 0xC8
; Sends an End-Of Interrupt signal to the 8259 interrupt controller.
PUSH AX
MOV AL, 0x20
OUT 0x20, AL
POP AX
; Returns.
STI
IRET
It appears to work now. When I get around to it I am going to see if I can intergrate some code I wrote that dumps all conventional memory to a file. That's why I wanted to create a TSR to begin with. Thank you all for your input!