/svarcom/trunk/command.c |
---|
87,7 → 87,47 |
unsigned short envsiz; |
}; |
/* max length of the cmdline storage (bytes) - includes also max length of |
* line loaded from a BAT file (no more than 255 bytes!) */ |
#define CMDLINE_MAXLEN 255 |
/* sets guard values at a few places in memory for later detection of |
* overflows via memguard_check() */ |
static void memguard_set(void) { |
BUFFER[sizeof(BUFFER) - 1] = 0xC7; |
BUFFER[sizeof(BUFFER) - (CMDLINE_MAXLEN + 3)] = 0xC7; |
} |
/* checks for valguards at specific memory locations, returns 0 on success */ |
static int memguard_check(unsigned short rmodseg) { |
/* check RMOD signature (would be overwritten in case of stack overflow */ |
static char msg[] = "!! MEMORY CORRUPTION ## DETECTED !!"; |
unsigned short far *rmodsig = MK_FP(rmodseg, 0x100 + 6); |
if (*rmodsig != 0x2019) { |
msg[22] = '1'; |
outputnl(msg); |
printf("rmodseg = %04X ; *rmodsig = %04X\r\n", rmodseg, *rmodsig); |
return(1); |
} |
/* check last BUFFER byte (could be overwritten by cmdline) */ |
if (BUFFER[sizeof(BUFFER) - 1] != 0xC7) { |
msg[22] = '2'; |
outputnl(msg); |
return(2); |
} |
/* check that cmdline BUFFER's end hasn't been touched by something else */ |
if (BUFFER[sizeof(BUFFER) - (CMDLINE_MAXLEN + 3)] != 0xC7) { |
msg[22] = '3'; |
outputnl(msg); |
return(3); |
} |
/* all good */ |
return(0); |
} |
/* parses command line the hard way (directly from PSP) */ |
static void parse_argv(struct config *cfg) { |
unsigned short i; |
607,10 → 647,6 |
} |
/* max length of the cmdline storage (bytes) - includes also max length of |
* line loaded from a BAT file (no more than 255 bytes!) */ |
#define CMDLINE_MAXLEN 255 |
int main(void) { |
static struct config cfg; |
static unsigned short far *rmod_envseg; |
638,6 → 674,9 |
if (rmod->flags & FLAG_EXEC_AND_QUIT) sayonara(rmod); |
} |
/* install a few guardvals in memory to detect some cases of overflows */ |
memguard_set(); |
rmod_envseg = MK_FP(rmod->rmodseg, RMOD_OFFSET_ENVSEG); |
lastexitcode = MK_FP(rmod->rmodseg, RMOD_OFFSET_LEXITCODE); |
666,9 → 705,13 |
/* cancel any redirections that may have been set up before */ |
redir_revert(); |
/* preset cmdline to point at the end of my general-purpose buffer */ |
cmdline = BUFFER + sizeof(BUFFER) - (CMDLINE_MAXLEN + 1); |
/* memory check */ |
memguard_check(rmod->rmodseg); |
/* preset cmdline to point at the end of my general-purpose buffer (with |
* one extra byte for the NULL terminator and another for memguard val) */ |
cmdline = BUFFER + sizeof(BUFFER) - (CMDLINE_MAXLEN + 2); |
/* (re)load translation strings if needed */ |
nls_langreload(BUFFER, *rmod_envseg); |
/svarcom/trunk/rmod.asm |
---|
19,20 → 19,23 |
SIG1 dw 0x1983 ; +0 |
SIG2 dw 0x1985 ; +2 |
SIG3 dw 0x2017 ; +4 |
SIG4 dw 0x2019 ; +6 |
SIG4 dw 0x2019 ; +6 this acts also as a guardval to detect stack overflows |
FFU_UNUSED dw 0 ; +8 |
; DOS int 21h functions that I use require at least 40 bytes of stack under |
; DOS-C (FreeDOS) kernel, so here I reserve 64 bytes juste to be sure |
STACKBUF db "XXX SVARCOM RMOD BY MATEUSZ VISTE XXXXXXXXXXXXXXXXXXXXXXXXXXXX" |
STACKPTR dw 0 |
; exit code of last application |
LEXCODE dw 0 ; +0Ah |
LEXCODE dw 0 ; +4Ah |
; offset of the COMSPEC variable in the environment block, 0 means "use |
; boot drive". this value is patched by the transient part of COMMAND.COM |
COMSPECPTR dw 0 ; +0Ch |
COMSPECPTR dw 0 ; +4Ch |
; fallback COMSPEC string used if no COMPSEC is present in the environment |
; drive. drive is patched by the transient part of COMMAND.COM |
COMSPECBOOT db "@:\COMMAND.COM", 0 ; +0Eh |
COMSPECBOOT db "@:\COMMAND.COM", 0 ; +4Eh |
; ExecParamRec used by INT 21h, AX=4b00 (load and execute program), 14 bytes: |
; offset size content |
40,12 → 43,12 |
; +2 4 address of command line to place at PSP:0080 |
; +6 4 address of an FCB to be placed at PSP:005c |
; +0Ah 4 address of an FCB to be placed at PSP:006c |
EXEC_PARAM_REC db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; +1Dh |
EXEC_PARAM_REC db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; +5Dh |
; Program to execute, preset by SvarCOM (128 bytes, ASCIIZ) ; +2Bh |
; Program to execute, preset by SvarCOM (128 bytes, ASCIIZ) ; +6Bh |
EXECPROG dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
skipsig: ; +ABh |
skipsig: ; +EBh |
; set up CS=DS=SS and point SP to my private stack buffer |
mov ax, cs |
145,8 → 148,3 |
CMDTAIL db 0x01, 0x0A, 0x0D |
ERRLOAD db "ERR x, FAILED TO LOAD COMMAND.COM", 13, 10, '$' |
; DOS int 21h functions that I use require at least 32 bytes of stack, here I |
; allocate 64 bytes to be sure |
STACKBUF db "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" |
STACKPTR db "xx" |
/svarcom/trunk/rmodinit.h |
---|
43,12 → 43,12 |
}; |
#define RMOD_OFFSET_ENVSEG 0x2C /* stored in rmod's PSP */ |
#define RMOD_OFFSET_LEXITCODE 0x10A |
#define RMOD_OFFSET_COMSPECPTR 0x10C |
#define RMOD_OFFSET_BOOTDRIVE 0x10E |
#define RMOD_OFFSET_EXECPARAM 0x11D |
#define RMOD_OFFSET_EXECPROG 0x12B |
#define RMOD_OFFSET_ROUTINE 0x1AB |
#define RMOD_OFFSET_LEXITCODE (0x100 + 0x4A) |
#define RMOD_OFFSET_COMSPECPTR (0x100 + 0x4C) |
#define RMOD_OFFSET_BOOTDRIVE (0x100 + 0x4E) |
#define RMOD_OFFSET_EXECPARAM (0x100 + 0x5D) |
#define RMOD_OFFSET_EXECPROG (0x100 + 0x6B) |
#define RMOD_OFFSET_ROUTINE (0x100 + 0xEB) |
struct rmod_props far *rmod_install(unsigned short envsize, unsigned char *rmodcore, unsigned short rmodcore_len); |
struct rmod_props far *rmod_find(unsigned short rmodcore_len); |