home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <dos.h>
- #include <dir.h>
- #include "intercep.h"
-
- #define MAXFILESIZE 20000 /* maximum template file size */
- #define MAXLINELEN 200 /* maximum output line length */
- #define AVGLINELEN 40 /* average line length */
-
- char template_text[ MAXFILESIZE ]; /* file text */
- char *templates[ MAXFILESIZE/AVGLINELEN ]; /* pointers to each line */
- int ntemplates; /* number of templates */
-
- /* copy template to dest, changing regname to regval throughout.
- * assumes dest is big enough to hold result.
- */
- void
- subst(char *regname, unsigned rval, char *template, char *dest)
- {
- char regval[5];
- if (regname[1] == 'H' || regname[1] == 'L')
- sprintf(regval, "%02X", rval);
- else
- sprintf(regval, "%04X", rval);
- while (*dest = *template) { /* copy through '\0' at end of string. */
- if (template[0] == regname[0] && template[1] == regname[1]) {
- dest = stpcpy(dest, regval);
- template += 2; /* all regnames are 2 chars long */
- }
- else {
- template++;
- dest++;
- }
- }
- }
-
- /* Read template file into buffer, setting pointers to
- * beginning of lines.
- * Sets template_text, templates and ntemplates.
- * Pads out interrupt IDs to 6 characters.
- * Returns number of lines.
- */
- int
- read_template_file(char *filename)
- {
- FILE *ifile;
- char inline[ MAXLINELEN ];
- char **nextline = templates;
- char *dest = template_text;
- char *q = template_text;
-
- if (! (ifile = fopen(filename, "rt")))
- return 0;
- while (fgets(inline, MAXLINELEN, ifile)) {
- char *p = inline;
- if (! isxdigit(inline[0]))
- continue; /* handle comment lines */
- *nextline++ = dest = q;
- while (isxdigit(*p))
- *q++ = *p++; /* copy initial hex string */
- while (q < dest+6)
- *q++ = ' '; /* pad out to 6 characters */
- *p = ' '; /* convert tab (or whatever) to space */
- while (*q++ = *p++)
- ; /* copy rest of line through null */
- while (q[-3] == '\\' && q[-2] == '\n') { /* continuation lines */
- if (p = fgets(inline, MAXLINELEN, ifile)) {
- q -= 3;
- *q++ = '\n';
- while (*q++ = *p++)
- ;
- }
- else
- goto on_eof;
- }
- }
- on_eof:
- *nextline = NULL;
- return (ntemplates = nextline - templates);
- }
-
- int compare_templates(char **t1, char **t2)
- {
- return(strnicmp(*t1, *t2, 6));
- }
-
- /* find a matching template given interrupt number and ax value
- * works from the most specific (all 6 characters)
- * back to the most general (just the 2 characters of the interrupt number).
- */
- char *find_template(int intnum, unsigned axval)
- {
- char proposed[ 7 ];
- char *key = proposed;
- char **found;
- char *ignoring = proposed + 6;
-
- sprintf(proposed, "%02X%04X", intnum, axval);
-
- while (ignoring > proposed) {
- if (found = bsearch(&key, templates, ntemplates,
- sizeof(char *), compare_templates))
- return(*found);
- /* else ignore 2 more characters */
- ignoring -= 2;
- ignoring[0] = ignoring[1] = ' ';
- }
- return NULL;
- }
-
- #define HI(u) (((u)&0xff00)>>8)
- #define LO(u) ((u)&0x00ff)
-
- /* read Swi_info records from input file
- * interpret them, and output to output file.
- */
- void
- interpret_file(FILE *ifp, FILE *ofp, char *progname, int longmode)
- {
- Swi_info rec;
- char s1[ MAXLINELEN ];
- char s2[ MAXLINELEN ];
- char *templ;
-
- if (progname != NULL)
- fprintf (ofp, "INTERCEPT/INTERPRET by Ned Konz 08/02/87\n"
- "dump of DOS/BIOS calls from program \"%s\"\n",
- progname);
- if (longmode)
- fprintf(ofp,
- " CS:IP INT AX BX CX DX DS ES SI DI BP\n");
-
- while (fread(&rec, sizeof(Swi_info), 1, ifp)) {
- if (templ = find_template(rec.intnum, rec.regs.ovl.old[2])) {
- subst("AX", rec.regs.ovl.old[2], templ, s1);
- subst("AH", HI(rec.regs.ovl.old[2]), s1, s2);
- subst("AL", LO(rec.regs.ovl.old[2]), s2, s1);
-
- subst("BX", rec.regs.ovl.old[1], s1, s2);
- subst("BH", HI(rec.regs.ovl.old[1]), s2, s1);
- subst("BL", LO(rec.regs.ovl.old[1]), s1, s2);
-
- subst("CX", rec.regs.ovl.old[0], s2, s1);
- subst("CH", HI(rec.regs.ovl.old[0]), s1, s2);
- subst("CL", LO(rec.regs.ovl.old[0]), s2, s1);
-
- subst("DX", rec.regs.dx, s1, s2);
- subst("DH", HI(rec.regs.dx), s2, s1);
- subst("DL", LO(rec.regs.dx), s1, s2);
-
- subst("BP", rec.regs.bp, s2, s1);
- subst("DI", rec.regs.di, s1, s2);
- subst("SI", rec.regs.si, s2, s1);
- subst("DS", rec.regs.ds, s1, s2);
- subst("ES", rec.regs.es, s2, s1);
-
- subst("CS", FP_SEG(rec.caller.ipcs), s1, s2);
- subst("IP", FP_OFF(rec.caller.ipcs), s2, s1);
- fprintf(ofp, "%Fp %s",
- (char far *)rec.caller.ipcs - 2, s1);
- }
-
- if ((templ==NULL) || longmode) {
- fprintf(ofp,
- "%Fp %2x %04x "
- "%04x %04x %04x "
- "%04x %04x %04x %04x %04x\n",
- (char far *)rec.caller.ipcs - 2, rec.intnum,
- rec.regs.ovl.old[2], /*AX*/
- rec.regs.ovl.old[1] /*BX*/, rec.regs.ovl.old[0],/*CX*/ rec.regs.dx,
- rec.regs.ds, rec.regs.es, rec.regs.si, rec.regs.di,
- rec.regs.bp);
- }
- } /*while*/
-
- return;
- }
-
- int
- main(int argc, char *argv[])
- {
- int longmode = 0;
- char *templfile = TFILENAME;
- char *progname = argv[0];
- FILE *ifp, *ofp;
-
- if (argc < 3) {
- fprintf(stderr, "INTERCEPT/INTERPRET by Ned Konz 08/02/87\n"
- "usage: %s [-l] [-t templ_file] "
- "infile outfile [progname]\n",
- argv[0]);
- exit(1);
- }
- argv++;
-
- while (argv[0][0] == '-') {
- if (! stricmp(argv[0], "-l")) { longmode++; }
- else if (! stricmp(argv[0], "-t")) { templfile = argv[1]; argv++; }
- else {
- fprintf(stderr, "%s: unknown switch \"%s\"\n", progname, argv[0]);
- exit(4);
- }
- argv++;
- }
-
- if (! read_template_file( searchpath(templfile) )) {
- fprintf(stderr, "%s: error during read of \"%s\"\n",
- progname, templfile);
- exit(5);
- }
- qsort(templates, ntemplates, sizeof(char *), compare_templates);
- if (! (ifp = fopen(argv[0], "rb"))) {
- fprintf(stderr, "%s: can't open input file \"%s\"\n",
- progname, argv[0]);
- exit(2);
- }
- if (! (ofp = fopen(argv[1], "wt"))) {
- fprintf(stderr, "%s: can't open output file \"%s\"\n",
- progname, argv[1]);
- exit(3);
- }
- interpret_file(ifp, ofp, argv[2], longmode);
- fclose(ifp);
- fclose(ofp);
- exit(0);
- }
-