home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 December / PCO_1298.ISO / filesbbs / os2 / fn128os2.arj / FN128OS2.ZIP / fn128os2 / src / gram.y < prev    next >
Encoding:
Lex Description  |  1998-10-02  |  12.7 KB  |  633 lines

  1. %{
  2. /*
  3.  # $Id: gram.y,v 1.7 1998/04/10 10:27:18 fbm Exp fbm $
  4.  # Copyright (C) 1997,1998 Farrell McKay
  5.  # All rights reserved.
  6.  #
  7.  # This file is part of the Fortify distribution, a toolkit for
  8.  # upgrading the cryptographic strength of the Netscape Navigator
  9.  # web browser, authored by Farrell McKay.
  10.  #
  11.  # This toolkit is provided to the recipient under the
  12.  # following terms and conditions:-
  13.  #   1.  This copyright notice must not be removed or modified.
  14.  #   2.  This toolkit may not be reproduced or included in any commercial
  15.  #       media distribution, or commercial publication (for example CD-ROM,
  16.  #       disk, book, magazine, journal) without first obtaining the author's
  17.  #       express permission.
  18.  #   3.  This toolkit, or any component of this toolkit, may not be
  19.  #       commercially resold, redeveloped, rewritten, enhanced or otherwise
  20.  #       used as the basis for commercial venture, without first obtaining
  21.  #       the author's express permission.
  22.  #   4.  Subject to the above conditions being observed (1-3), this toolkit
  23.  #       may be freely reproduced or redistributed.
  24.  #   5.  This software is provided "as-is", without express or implied
  25.  #       warranty.  In no event shall the author be liable for any direct,
  26.  #       indirect or consequential damages however caused.
  27.  #   6.  Subject to the above conditions being observed (1-5),
  28.  #       this toolkit may be used at no cost to the recipient.
  29.  #
  30.  # Farrell McKay
  31.  # Wayfarer Systems Pty Ltd        contact@fortify.net
  32.  */
  33.  
  34. #include <assert.h>
  35. #include <ctype.h>
  36. #include <stdlib.h>
  37. #include <time.h>
  38. #include <stdio.h>
  39. #include <sys/types.h>
  40. #include "misc.h"
  41. #include "morpher.h"
  42.  
  43. #define isoctal(a)    ((a) >= '0' && (a) <= '7')
  44.  
  45. extern int        yyparse();
  46. extern int        yylex();
  47. #if defined(GNU_WIN32)
  48. extern char        *yytext;
  49. #else
  50. extern char        yytext[];
  51. #endif
  52. extern int        yyleng;
  53.  
  54. static int        unescape(char *src, int len);
  55.  
  56. static morph_set    *newmorphset;
  57. static morph_t        *newmorph;
  58. static char        *newtoken;
  59.  
  60. static char        buff[1024];
  61.  
  62. %}
  63.  
  64. %token GRAMMAR TARGET TEXT_OFFSET DATA_OFFSET RODATA_OFFSET
  65. %token TOKEN STRING NUM
  66. %token INIT SEGMENT MSG GRADE BASE OFFSET OLD NEW CONTEXT
  67. %token TEXT DATA RODATA
  68. %token PRINT ASSERT PTR ADDR EQ NE LT LE GT GE
  69.  
  70. %union {
  71.     enum verb_t    vt;
  72.     enum op_t    ot;
  73.     unsigned long    ul;
  74.     morph_t        *pmorph;
  75.     vec_t        *pvec;
  76.     exp_t        *pexp;
  77. }
  78.  
  79. %type <vt> verb
  80. %type <ot> attr_name bool_op
  81. %type <ul> seg_id num
  82. %type <pmorph> morph
  83. %type <pvec> vector
  84. %type <pexp> exp
  85.  
  86. %%
  87.  
  88. start:        headers opt_morphs
  89.         {
  90.             morph_t    *p;
  91.  
  92.             p = find_morph(newmorphset, "_main");
  93.             if (p)
  94.                 newmorphset->main = p->base + p->offset;
  95.  
  96.             /* if (newmorphset->main == ADDR_UNKN) {
  97.                 yyerror("No _main definition");
  98.             } */
  99.         }
  100.         | error
  101.         {
  102.             yyerror("Parse error");
  103.         };
  104.  
  105. headers:    init '{' grammar header_attrs '}'
  106.         {
  107. #if 0
  108.             int    i;
  109.  
  110.             /* check for missing attributes in header */
  111.             for (i = 0; i < NSEGS; i++) {
  112.                 if (newmorphset->offsets[i] == 0) {
  113.                     sprintf(buff, "Init section: No offset for %s segment.",
  114.                         seg_name(i));
  115.                     yyerror(buff);
  116.                 }
  117.             }
  118. #endif
  119.         };
  120.  
  121. init:        INIT
  122.         {
  123.             newmorphset = _calloc(1, sizeof(morph_set));
  124.         };
  125.  
  126. grammar:    GRAMMAR num '.' num
  127.         {
  128.             newmorphset->main = ADDR_UNKN;
  129.             newmorphset->nmorphs = 0;
  130.             newmorphset->grammar_major = $2;
  131.             newmorphset->grammar_minor = $4;
  132.  
  133.             if (newmorphset->grammar_major > GRAMMAR_MAJOR ||
  134.                 (newmorphset->grammar_major == GRAMMAR_MAJOR &&
  135.                     newmorphset->grammar_minor > GRAMMAR_MINOR))
  136.                 yyerror("Unsupported grammar version.");
  137.         };
  138.  
  139. header_attrs:    header_attrs header_attr
  140.         | header_attr
  141.         ;
  142.  
  143. header_attr:    TARGET STRING
  144.         {
  145.             if (newmorphset->target != (char *)0)
  146.                 free(newmorphset->target);
  147.             newmorphset->target = _strndup(yytext+1, yyleng-2);
  148.         }
  149.         | TEXT_OFFSET NUM
  150.         {
  151.             newmorphset->offsets[SEG_TEXT] = (long) yylval.ul;
  152.         }
  153.         | DATA_OFFSET NUM
  154.         {
  155.             newmorphset->offsets[SEG_DATA] = (long) yylval.ul;
  156.         }
  157.         | RODATA_OFFSET NUM
  158.         {
  159.             newmorphset->offsets[SEG_RODATA] = (long) yylval.ul;
  160.         };
  161.  
  162. opt_morphs:    morphs
  163.         | /* empty */
  164.         ;
  165.  
  166. morphs:     morphs morph
  167.         {
  168.             int n = ++(newmorphset->morphs_sz);
  169.             newmorphset->morphs =
  170.                 (morph_t **) _realloc((void *) newmorphset->morphs,
  171.                 (n * sizeof(morph_t *)));
  172.             newmorphset->morphs[n-1] = $2;
  173.         }
  174.         | morph
  175.         {
  176.             newmorphset->morphs_sz = 1;
  177.             newmorphset->morphs = (morph_t **) _malloc(sizeof(morph_t *));
  178.             newmorphset->morphs[0] = $1;
  179.         };
  180.  
  181. morph:        morph_name '{' morph_attrs '}'
  182.         {
  183.             /* check for missing attributes in morph definition */
  184.             if (newmorph->seg == SEG_UNKN) {
  185.                 sprintf(buff, "Morph %s: No segment attribute", newmorph->name);
  186.                 yyerror(buff);
  187.             }
  188.             if (newmorph->base == ADDR_UNKN) {
  189.                 sprintf(buff, "Morph %s: No base address", newmorph->name);
  190.                 yyerror(buff);
  191.             }
  192.             if (newmorph->old.len <= 0) {
  193.                 sprintf(buff, "Morph %s: No old value", newmorph->name);
  194.                 yyerror(buff);
  195.             }
  196.             if (!newmorph->is_context && (newmorph->old.len != newmorph->new.len)) {
  197.                 sprintf(buff, "Morph %s: Old length != new length", newmorph->name);
  198.                 yyerror(buff);
  199.             }
  200.             if (!newmorph->is_context)
  201.                 ++(newmorphset->nmorphs);
  202.             $$ = newmorph;
  203.         };
  204.  
  205. morph_name:    TOKEN
  206.         {
  207.             newmorph = (morph_t *) _calloc(1, sizeof(morph_t));
  208.             newmorph->name = _strndup(yytext, yyleng);
  209.             newmorph->seg = SEG_UNKN;
  210.             newmorph->base = ADDR_UNKN;
  211.             newmorph->offset = 0;
  212.             newmorph->grade = DEFAULT_GRADE;
  213.         };
  214.  
  215. morph_attrs:    morph_attrs morph_attr
  216.         | morph_attr
  217.         ;
  218.  
  219. morph_attr:    SEGMENT seg_id
  220.         {
  221.             newmorph->seg = $2;
  222.         }
  223.         | MSG STRING
  224.         {
  225.             if (newmorph->msg != (char *)0)
  226.                 free(newmorph->msg);
  227.             newmorph->msg = _strndup(yytext+1, yyleng-2);
  228.         }
  229.         | GRADE NUM
  230.         {
  231.             newmorph->grade = yylval.ul;
  232.         }
  233.         | BASE NUM
  234.         {
  235.             newmorph->base = yylval.ul;
  236.         }
  237.         | OFFSET NUM
  238.         {
  239.             newmorph->offset = (long) yylval.ul;
  240.         }
  241.         | OLD vector
  242.         {
  243.             if (newmorph->old.len != 0)
  244.                 free(newmorph->old.data);
  245.             newmorph->old = *($2);
  246.             free($2);
  247.         }
  248.         | NEW vector
  249.         {
  250.             if (newmorph->new.len != 0)
  251.                 free(newmorph->new.data);
  252.             newmorph->new = *($2);
  253.             free($2);
  254.         }
  255.         | CONTEXT vector
  256.         {
  257.             if (newmorph->old.len != 0)
  258.                 free(newmorph->old.data);
  259.             newmorph->old = *($2);
  260.             newmorph->is_context = 1;
  261.             free($2);
  262.         }
  263.         | verb exp
  264.         {
  265.             cmd_t    *cp, *p;
  266.  
  267.             cp = (cmd_t *) _calloc(1, sizeof(cmd_t));
  268.             cp->verb = $1;
  269.             cp->exp = $2;
  270.             if (newmorph->cmds == (cmd_t *)0)
  271.                 newmorph->cmds = cp;
  272.             else {
  273.                 for (p = newmorph->cmds; p->next;)
  274.                     p = p->next;
  275.                 p->next = cp;
  276.             }
  277.         };
  278.  
  279. verb:        PRINT
  280.         {
  281.             $$ = print;
  282.         }
  283.         | ASSERT
  284.         {
  285.             $$ = assert;
  286.         };
  287.  
  288. seg_id:        TEXT
  289.         {
  290.             $$ = SEG_TEXT;
  291.         }
  292.         | DATA
  293.         {
  294.             $$ = SEG_DATA;
  295.         }
  296.         | RODATA
  297.         {
  298.             $$ = SEG_RODATA;
  299.         };
  300.  
  301. vector:        vector NUM
  302.         {
  303.             int n = ++(($1)->len);
  304.             ($1)->data = (char *) _realloc((void *) (($1)->data),
  305.                             (n * sizeof(unsigned char)));
  306.             ($1)->data[n-1] = (unsigned char) yylval.ul;
  307.             $$ = $1;
  308.         }
  309.         | NUM
  310.         {
  311.             $$ = _malloc(sizeof(vec_t));
  312.             ($$)->format = VEC_NUM_FMT;
  313.             ($$)->len = 1;
  314.             ($$)->data = (unsigned char *) _malloc(sizeof(unsigned char));
  315.             ($$)->data[0] = (unsigned char) yylval.ul;
  316.         }
  317.         | STRING
  318.         {
  319.             $$ = _malloc(sizeof(vec_t));
  320.             ($$)->format = VEC_STR_FMT;
  321.             ($$)->data = (unsigned char *) _strndup(yytext+1, yyleng-2);
  322.             ($$)->len = yyleng - 2;
  323.             ($$)->len = unescape(($$)->data, ($$)->len);
  324.         };
  325.  
  326. exp:        num
  327.         {
  328.             $$ = (exp_t *) _calloc(1, sizeof(exp_t));
  329.             ($$)->op = constant;
  330.             ($$)->nargs = 1;
  331.             ($$)->arg1.ul = $1;
  332.         }
  333.         | PTR '[' num ']'
  334.         {
  335.             $$ = (exp_t *) _calloc(1, sizeof(exp_t));
  336.             ($$)->op = ptr;
  337.             ($$)->nargs = 1;
  338.             ($$)->arg1.ul = $3;
  339.         }
  340.         | PTR '[' num ',' num ']'
  341.         {
  342.             if ($3 >= $5) {
  343.                 sprintf(buff, "Morph %s: bad 'ptr' args", newmorph->name);
  344.                 yyerror(buff);
  345.             }
  346.             $$ = (exp_t *) _calloc(1, sizeof(exp_t));
  347.             ($$)->op = ptr;
  348.             ($$)->nargs = 2;
  349.             ($$)->arg1.ul = $3;
  350.             ($$)->arg2.ul = $5;
  351.         }
  352.         | opt_token attr_name
  353.         {
  354.             $$ = (exp_t *) _calloc(1, sizeof(exp_t));
  355.             ($$)->op = $2;
  356.             ($$)->nargs = 1;
  357.             ($$)->arg1.cp = newtoken;
  358.         }
  359.         |
  360.         exp bool_op exp
  361.         {
  362.             $$ = (exp_t *) _calloc(1, sizeof(exp_t));
  363.             ($$)->op = $2;
  364.             ($$)->nargs = 2;
  365.             ($$)->arg1.p = $1;
  366.             ($$)->arg2.p = $3;
  367.         };
  368.  
  369. opt_token:    TOKEN
  370.         {
  371.             newtoken = _strndup(yytext, yyleng);
  372.         } '.'
  373.         | /* empty */
  374.         {
  375.             newtoken = NULL;
  376.         };
  377.  
  378. attr_name:    BASE
  379.         {
  380.             $$ = base;
  381.         }
  382.         | ADDR
  383.         {
  384.             $$ = addr;
  385.         }
  386.         | OFFSET
  387.         {
  388.             $$ = offset;
  389.         };
  390.  
  391. bool_op:    EQ
  392.         {
  393.             $$ = eq;
  394.         }
  395.         | NE
  396.         {
  397.             $$ = ne;
  398.         }
  399.         | LT
  400.         {
  401.             $$ = lt;
  402.         }
  403.         | LE
  404.         {
  405.             $$ = le;
  406.         }
  407.         | GT
  408.         {
  409.             $$ = gt;
  410.         }
  411.         | GE
  412.         {
  413.             $$ = ge;
  414.         };
  415.  
  416. num:        NUM
  417.         {
  418.             $$ = (long) yylval.ul;
  419.         };
  420.  
  421. %%
  422.  
  423. morph_set *
  424. parse(FILE* fp)
  425. {
  426.     lex_file_input(fp);
  427.     yyparse();
  428.     return newmorphset;
  429. }
  430.  
  431. morph_t *
  432. find_morph(morph_set *ms, char *name)
  433. {
  434.     int    i;
  435.     morph_t    *p = (morph_t *)0;
  436.  
  437.     for (i = 0; i < ms->morphs_sz; i++) {
  438.         p = ms->morphs[i];
  439.         if (strcmp(p->name, name) == 0)
  440.             break;
  441.     }
  442.     return p;
  443. }
  444.  
  445. static int
  446. unescape(char *src, int len)
  447. {
  448.     register char    *ptr = src;
  449.     char        *end = ptr + len;
  450.     char        *tgt = ptr;
  451.     char        ch;
  452.  
  453.     while (ptr < end) {
  454.         if (*ptr != '\\')
  455.             *tgt++ = *ptr++;
  456.         else if (++ptr < end) {
  457.             ch = *ptr++;
  458.             if (ch == '\\') {
  459.                 *tgt++ = '\\';
  460.             } else if (isoctal(ch)) {
  461.                 ch -= '0';
  462.                 if (ptr < end && isoctal(*ptr))
  463.                     ch = (ch << 3) + (*ptr++ - '0');
  464.                 if (ptr < end && isoctal(*ptr))
  465.                     ch = (ch << 3) + (*ptr++ - '0');
  466.                 *tgt++ = ch;
  467.             }
  468.         }
  469.     }
  470.     return (tgt - src);
  471. }
  472.  
  473. static void
  474. dump_vec(FILE *fp, unsigned char *src, int len, int perline, int format)
  475. {
  476.     int    i;
  477.  
  478.     if (format == VEC_NUM_FMT) {
  479.         if (len == 0)
  480.             fputs("---------------", fp);        /* Highlight empty vectors. */
  481.         for (i = 0; i < len; i++) {
  482.             if (i > 0 && (i % perline) == 0) {
  483.                 fputs("\n\t\t\t", fp);
  484.             }
  485.             fprintf(fp, "0x%02x ", src[i]);
  486.         }
  487.         fputs("\n", fp);
  488.     } else if (format == VEC_STR_FMT) {
  489.         fputc('"', fp);
  490.         for (; len-- > 0; src++) {
  491.             if (*src == '\\')
  492.                 fputs("\\\\", fp);
  493.             else if (isprint(*src))
  494.                 fputc(*src, fp);
  495.             else
  496.                 fprintf(fp, "\\%03o", (unsigned int) *src);
  497.         }
  498.         fputs("\"\n", fp);
  499.     }
  500. }
  501.  
  502. void
  503. dump_bool_op(FILE *fp, enum op_t op)
  504. {
  505.     if (op == eq)
  506.         fputs("==", fp);
  507.     else if (op == ne)
  508.         fputs("!=", fp);
  509.     else if (op == lt)
  510.         fputs("<", fp);
  511.     else if (op == le)
  512.         fputs("<=", fp);
  513.     else if (op == gt)
  514.         fputs(">", fp);
  515.     else if (op == ge)
  516.         fputs(">=", fp);
  517. }
  518.  
  519. static void
  520. dump_exp(FILE *fp, exp_t *ep)
  521. {
  522.     if (ep->op == constant) {
  523.         fprintf(fp, "%ld", ep->arg1.ul);
  524.     }
  525.     else if (ep->op == ptr) {
  526.         fprintf(fp, "ptr[%ld", ep->arg1.ul);
  527.         if (ep->nargs == 2)
  528.             fprintf(fp, ",%ld", ep->arg2.ul);
  529.         fputs("]", fp);
  530.     }
  531.     else if (ep->op == base || ep->op == addr || ep->op == offset) {
  532.         if (ep->arg1.cp)
  533.             fprintf(fp, "%s.", ep->arg1.cp);
  534.         if (ep->op == base)
  535.             fputs("base", fp);
  536.         else if (ep->op == addr)
  537.             fputs("addr", fp);
  538.         else if (ep->op == offset)
  539.             fputs("offset", fp);
  540.     }
  541.     else if (is_bool_op(ep->op)) {
  542.         dump_exp(fp, ep->arg1.p);
  543.         fputs(" ", fp);
  544.         dump_bool_op(fp, ep->op);
  545.         fputs(" ", fp);
  546.         dump_exp(fp, ep->arg2.p);
  547.     }
  548. }
  549.  
  550. static void
  551. dump_cmd(FILE *fp, cmd_t *cp)
  552. {
  553.     if (cp->verb == print)
  554.         fputs("\tprint\t\t", fp);
  555.     else if (cp->verb == assert)
  556.         fputs("\tassert\t\t", fp);
  557.     else {
  558.         return;
  559.     }
  560.     dump_exp(fp, cp->exp);
  561.     fputs("\n", fp);
  562. }
  563.  
  564. void
  565. dump_morph(FILE *fp, morph_set *ms, morph_t *mp, void (*eval_fn)(), void *vp)
  566. {
  567.     cmd_t    *cp;
  568.  
  569.     fprintf(fp, "\n%s {\n", mp->name);
  570.     fprintf(fp, "\tsegment\t\t%s\n", seg_name(mp->seg));
  571.     if (mp->msg)
  572.         fprintf(fp, "\tmsg\t\t\"%s\"\n", mp->msg);
  573.     if (mp->grade != DEFAULT_GRADE)
  574.         fprintf(fp, "\tgrade\t\t%d\n", mp->grade);
  575.     fprintf(fp, "\tbase\t\t0x%lx\n", mp->base);
  576.     if (mp->seg == SEG_TEXT || mp->offset != 0)
  577.         fprintf(fp, "\toffset\t\t0x%lx\n", mp->offset);
  578.     if (mp->is_context) {
  579.         fputs("\tcontext\t\t", fp);
  580.         dump_vec(fp, mp->old.data, mp->old.len, 4, mp->old.format);
  581.     } else {
  582.         fputs("\told_value\t", fp);
  583.         dump_vec(fp, mp->old.data, mp->old.len, 4, mp->old.format);
  584.         fputs("\tnew_value\t", fp);
  585.         dump_vec(fp, mp->new.data, mp->new.len, 4, mp->new.format);
  586.     }
  587.  
  588.     for (cp = mp->cmds; cp; cp = cp->next) {
  589.         dump_cmd(fp, cp);
  590.         if (eval_fn)
  591.             (*eval_fn)(cp, ms, mp, fp, vp);
  592.     }
  593.  
  594.     fputs("}\n", fp);
  595. }
  596.  
  597. static void
  598. dump_seg_offset(FILE *fp, char *label, long val)
  599. {
  600.     if (val < 0)
  601.         fprintf(fp, "\t%s\t-0x%lx\n", label, -val);
  602.     else
  603.         fprintf(fp, "\t%s\t0x%lx\n", label, val);
  604. }
  605.  
  606. void
  607. dump_init(FILE *fp, morph_set *ms)
  608. {
  609.     time_t    tm;
  610.  
  611.     tm = time((time_t *)0);
  612.     fprintf(fp, "\n; Morphs dump generated at %s", ctime(&tm));
  613.  
  614.     fputs("\ninit {\n", fp);
  615.     fprintf(fp, "\tgrammar\t\t%d.%d\n", GRAMMAR_MAJOR, GRAMMAR_MINOR);
  616.     fprintf(fp, "\ttarget\t\t\"%s\"\n", ms->target);
  617.     dump_seg_offset(fp, "text_offset", ms->offsets[SEG_TEXT]);
  618.     dump_seg_offset(fp, "data_offset", ms->offsets[SEG_DATA]);
  619.     dump_seg_offset(fp, "rodata_offset", ms->offsets[SEG_RODATA]);
  620.     /* fprintf(fp, "\tmain\t\t0x%x\n", ms->main); */
  621.     fputs("}\n", fp);
  622. }
  623.  
  624. void
  625. dump_set(FILE *fp, morph_set *ms, void (*eval_fn)(), void *vp)
  626. {
  627.     int    i;
  628.  
  629.     dump_init(fp, ms);
  630.     for (i = 0; i < ms->morphs_sz; i++)
  631.         dump_morph(fp, ms, ms->morphs[i], eval_fn, vp);
  632. }
  633.