home *** CD-ROM | disk | FTP | other *** search
- /*
- # $Id: morpher.c,v 1.7 1998/04/10 10:27:56 fbm Exp fbm $
- # Copyright (C) 1997,1998 Farrell McKay
- # All rights reserved.
- #
- # This file is part of the Fortify distribution, a toolkit for
- # upgrading the cryptographic strength of the Netscape Navigator
- # web browser, authored by Farrell McKay.
- #
- # This toolkit is provided to the recipient under the
- # following terms and conditions:-
- # 1. This copyright notice must not be removed or modified.
- # 2. This toolkit may not be reproduced or included in any commercial
- # media distribution, or commercial publication (for example CD-ROM,
- # disk, book, magazine, journal) without first obtaining the author's
- # express permission.
- # 3. This toolkit, or any component of this toolkit, may not be
- # commercially resold, redeveloped, rewritten, enhanced or otherwise
- # used as the basis for commercial venture, without first obtaining
- # the author's express permission.
- # 4. Subject to the above conditions being observed (1-3), this toolkit
- # may be freely reproduced or redistributed.
- # 5. This software is provided "as-is", without express or implied
- # warranty. In no event shall the author be liable for any direct,
- # indirect or consequential damages however caused.
- # 6. Subject to the above conditions being observed (1-5),
- # this toolkit may be used at no cost to the recipient.
- #
- # Farrell McKay
- # Wayfarer Systems Pty Ltd contact@fortify.net
- */
-
- #include <ctype.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <unistd.h>
-
- #include "misc.h"
- #include "index.h"
- #include "morpher.h"
- #include "os2lx.h"
-
-
- static void
- show_vec(FILE *f, unsigned char *src, int len, int format)
- {
- if (len > 0) {
- if (format == VEC_NUM_FMT) {
- char pre = '[';
- while (len-- > 0) {
- fprintf(f, "%c%02x", pre, (unsigned int) *src++);
- pre = ' ';
- }
- fprintf(f, "]");
- } else if (format == VEC_STR_FMT) {
- fputc('"', f);
- for (; len-- > 0; src++) {
- if (isprint(*src))
- fputc(*src, f);
- else
- fprintf(f, "\\%03o", (unsigned int) *src);
- }
- fputc('"', f);
- }
- }
- }
-
- #define MAXMORPHLEN 1024
-
- static int
- apply_morphs(int tgt, morph_set *ms, int old_grade, int new_grade, int nowrite, int verbose, int *count)
- {
- int i;
- int cmp;
- int candidates = 0;
- morph_t *p;
- off_t offset;
- unsigned char tmp[MAXMORPHLEN];
- vec_t *old, *new;
- int errs = 0;
-
- for (i = 0; i < ms->morphs_sz; i++) {
- p = ms->morphs[i];
- if (p->is_context)
- continue;
-
- if (new_grade < old_grade && p->grade <= old_grade && p->grade > new_grade) {
- old = &p->new;
- new = &p->old;
- }
- else if (new_grade > old_grade && p->grade > old_grade && p->grade <= new_grade) {
- old = &p->old;
- new = &p->new;
- }
- else
- continue;
-
- candidates++;
- if (new->len > MAXMORPHLEN) {
- errs++;
- fprintf(stderr,
- "Morph \"%s\": woops, this morph is too big!\n",
- p->name);
- continue;
- }
- if (verbose) {
- cmp = memcmp((void *) old->data, (void *) new->data, old->len);
- if (cmp == 0) {
- fprintf(stderr,
- "Morph \"%s\": Warning: morph changes nothing ??!\n",
- p->name);
- }
-
- printf("At file offset 0x%06lx, replacing ", p->filepos);
- show_vec(stdout, old->data, old->len, old->format);
- printf(" with ");
- show_vec(stdout, new->data, new->len, new->format);
- printf("\n");
- }
-
- offset = lseek(tgt, (off_t) p->filepos, SEEK_SET);
- if (offset == -1) {
- errs++;
- fprintf(stderr,
- "Morph \"%s\": error locating offset 0x%08lx [run-time 0x%lx]: ",
- p->name, p->filepos, p->base + p->offset);
- perror("");
- continue;
- }
-
- if (read(tgt, (char *) tmp, old->len) != old->len) {
- errs++;
- fprintf(stderr,
- "Morph \"%s\": error reading %d bytes at 0x%08lx: ",
- p->name, old->len, p->filepos);
- perror("");
- continue;
- }
-
- cmp = memcmp((void *) tmp, (void *) old->data, (size_t) old->len);
- if (cmp != 0) {
- errs++;
- fprintf(stderr, "Morph \"%s\": data mismatch: expected ", p->name);
- show_vec(stderr, old->data, old->len, VEC_NUM_FMT);
- fprintf(stderr, ", found ");
- show_vec(stderr, tmp, old->len, VEC_NUM_FMT);
- fprintf(stderr, "\n");
- continue;
- }
-
- if (!nowrite) {
- offset = lseek(tgt, (off_t) p->filepos, SEEK_SET);
- if (offset == -1) {
- errs++;
- fprintf(stderr,
- "Morph \"%s\": error repositioning at address 0x%08lx [run-time 0x%lx]: ",
- p->name, p->filepos, p->base + p->offset);
- perror("");
- continue;
- }
- if (write(tgt, (char *) new->data, new->len) != new->len) {
- errs++;
- fprintf(stderr,
- "Morph \"%s\": error writing data to 0x%08lx [run-time 0x%lx]: ",
- p->name, p->filepos, p->base + p->offset);
- perror("");
- continue;
- }
- }
- }
- *count = candidates;
- return errs;
- }
-
- int
- morpher(char *target_name, char *morph_file, index_entry_t *ent, int nowrite, int old_grade, int new_grade, int verbose)
- {
- int i, tgt, errs, flags;
- lxfile_t *lx = NULL;
- int candidates = 0;
- FILE *mf;
- morph_set *ms;
-
- flags = nowrite? OPENFL(O_RDONLY): OPENFL(O_RDWR);
- tgt = open(target_name, flags, 0666);
- if (tgt == -1) {
- fprintf(stderr, "Cannot open \"%s\": ", target_name);
- perror("");
- fprintf(stderr, "Perhaps you are running Netscape at the moment?\n");
- return 1;
- }
-
- mf = fopen(morph_file, "r");
- if (mf == NULL) {
- fprintf(stderr, "Woops: cannot open \"%s\": ", morph_file);
- perror("");
- fprintf(stderr, "Perhaps your Fortify distribution was not unpacked correctly?\n");
- fprintf(stderr, "Please refer to the README file for full unpacking instructions.\n");
- return 1;
- }
-
- ms = parse(mf);
-
- if (is_lx_entry(ent))
- lx = lxFile_is_lx(tgt);
-
- for (i = 0; i < ms->morphs_sz; i++) {
- morph_t *p = ms->morphs[i];
- if (lx)
- p->filepos = lxFile_get_offset(lx, p->base + p->offset);
- else
- p->filepos = p->base + p->offset - ms->offsets[p->seg];
- }
-
- errs = apply_morphs(tgt, ms, old_grade, new_grade, 1, verbose, (int *) &candidates);
- if (errs == 0 && ms->nmorphs > 0 && nowrite == 0) {
- errs = apply_morphs(tgt, ms, old_grade, new_grade, nowrite, 0, (int *) &candidates);
- }
- else {
- fprintf(stderr,
- "%d errors from %d potential morphs.\n",
- errs, candidates);
- fprintf(stderr, "No changes made to \"%s\".\n", target_name);
- }
-
- close(tgt);
- lxFile_free(lx);
- fclose(mf);
- return ((errs > 0)? 1: 0);
- }
-