|
|
1.1 ! root 1: /* ! 2: * File: coffpatch.c ! 3: * ! 4: * Purpose: write into a coff file ! 5: * ! 6: * $Log: coffpatch.c,v $ ! 7: * Revision 1.1 92/10/05 13:10:42 bin ! 8: * Initial revision ! 9: * ! 10: */ ! 11: ! 12: /* ! 13: * ---------------------------------------------------------------------- ! 14: * Includes. ! 15: */ ! 16: #include <stdio.h> ! 17: #include <fcntl.h> ! 18: #include <errno.h> ! 19: #include <coff.h> ! 20: #include <sys/types.h> ! 21: ! 22: /* ! 23: * ---------------------------------------------------------------------- ! 24: * Definitions. ! 25: * Constants. ! 26: * Macros with argument lists. ! 27: * Typedefs. ! 28: * Enums. ! 29: */ ! 30: ! 31: /* ! 32: * ---------------------------------------------------------------------- ! 33: * Functions. ! 34: * Import Functions. ! 35: * Export Functions. ! 36: * Local Functions. ! 37: */ ! 38: int coffpatch(); ! 39: ! 40: /* ! 41: * ---------------------------------------------------------------------- ! 42: * Global Data. ! 43: * Import Variables. ! 44: * Export Variables. ! 45: * Local Variables. ! 46: */ ! 47: extern char xflag; ! 48: ! 49: /* ! 50: * ---------------------------------------------------------------------- ! 51: * Code. ! 52: * ! 53: * Perform peeks/patches as formatted by coffp0() in asypatch.c ! 54: * ! 55: * Return nonzero if success; zero if failure. ! 56: */ ! 57: ! 58: int ! 59: coffpatch(fname, sym, stbl, buf, len, do_read) ! 60: char *fname; ! 61: SYMENT *sym; ! 62: char *stbl, *buf; ! 63: int len, do_read; ! 64: { ! 65: int ret = 0; ! 66: int fd, err; ! 67: int rwct, i; ! 68: static FILEHDR mainhdr; ! 69: static AOUTHDR opthdr; ! 70: static SCNHDR sh; ! 71: long seek, sought; ! 72: ! 73: long text_size; /* Size of text section in bytes. */ ! 74: vaddr_t text_addr; /* Virtual memory base address for text. */ ! 75: short text_scnum; /* Section number of text section. */ ! 76: fsize_t text_base; /* File offset of start of text section. */ ! 77: ! 78: long data_size; /* Size of data section in bytes. */ ! 79: vaddr_t data_addr; /* Virtual memory base address for data. */ ! 80: short data_scnum; /* Section number of data section. */ ! 81: fsize_t data_base; /* File offset of start of data section. */ ! 82: ! 83: /* ! 84: * Open the file to be patched. ! 85: */ ! 86: if ((fd=open(fname, O_RDONLY)) < 0) { ! 87: err = errno; ! 88: printf(stderr, "Cannot open %s\n", fname); ! 89: printf("Error [%d] {%s}\n", err, sys_errlist[err]); ! 90: exit(1); ! 91: /* goto no_close_fd; */ ! 92: } ! 93: lseek(fd, 0, 0); ! 94: ! 95: /* ! 96: * Read filehdr. ! 97: */ ! 98: if (-1 == read(fd, &mainhdr, sizeof(FILEHDR))) { ! 99: perror(fname); ! 100: fprintf(stderr, "Cannot read executable header.\n"); ! 101: goto close_fd; ! 102: } ! 103: ! 104: /* ! 105: * Check for valid magic and length of optional header. ! 106: */ ! 107: if (mainhdr.f_magic != C_386_MAGIC || (mainhdr.f_opthdr < sizeof(opthdr))) { ! 108: fprintf(stderr, "Bad magic (not COFF) in %s.\n", fname); ! 109: goto close_fd; ! 110: } ! 111: ! 112: /* ! 113: *Read the optional header. ! 114: */ ! 115: if (-1 == read(fd, &opthdr, sizeof(AOUTHDR))) { ! 116: perror(fname); ! 117: fprintf(stderr, "Cannot read optional header.\n"); ! 118: goto close_fd; ! 119: } ! 120: ! 121: /* ! 122: * Fill in the parameters we can get from the opthdr. ! 123: */ ! 124: text_size = opthdr.tsize; ! 125: text_addr = opthdr.text_start; ! 126: ! 127: data_size = opthdr.dsize; ! 128: data_addr = opthdr.data_start; ! 129: ! 130: /* ! 131: * Read section headers for offsets. ! 132: */ ! 133: text_scnum = -1; /* Mark as not found. */ ! 134: data_scnum = -1; /* Mark as not found. */ ! 135: for (i = 1; i <= mainhdr.f_nscns; ++i) { ! 136: if (-1 == read(fd, &sh, sizeof(SCNHDR))) { ! 137: perror(fname); ! 138: fprintf(stderr, "Cannot read section header.\n"); ! 139: goto close_fd; ! 140: } ! 141: ! 142: if (STYP_TEXT == sh.s_flags) { ! 143: text_scnum = i; ! 144: text_base = sh.s_scnptr; ! 145: } else if (STYP_DATA == sh.s_flags) { ! 146: data_scnum = i; ! 147: data_base = sh.s_scnptr; ! 148: } /* else ignore this section header. */ ! 149: } ! 150: ! 151: /* ! 152: * Did we find both sections? ! 153: */ ! 154: if (-1 == text_scnum) { ! 155: fprintf(stderr, "No text section in %s.\n", fname); ! 156: } ! 157: ! 158: if (-1 == data_scnum) { ! 159: fprintf(stderr, "No data section in %s.\n", fname); ! 160: } ! 161: ! 162: /* ! 163: * Range check the patch address. ! 164: */ ! 165: if (sym->n_scnum == text_scnum) { ! 166: if ((sym->n_value < text_addr) || ! 167: (sym->n_value + len > text_addr + text_size) ) { ! 168: ! 169: fprintf(stderr, "Symbol out of range for text section.\n"); ! 170: fprintf(stderr, "%s: %x\n", ! 171: stbl + sym->n_offset - sizeof(long), ! 172: sym->n_value); ! 173: goto close_fd; ! 174: } ! 175: } else if (sym->n_scnum == data_scnum) { ! 176: if ((sym->n_value < data_addr) || ! 177: (sym->n_value + len > data_addr + data_size) ) { ! 178: ! 179: fprintf(stderr, "Symbol out of range for data section.\n"); ! 180: fprintf(stderr, "%s: %x\n", ! 181: stbl + sym->n_offset - sizeof(long), ! 182: sym->n_value); ! 183: goto close_fd; ! 184: } ! 185: } else { ! 186: fprintf(stderr, ! 187: "Illegal section number %d for symbol %s.\n", ! 188: sym->n_scnum, ! 189: stbl + sym->n_offset - sizeof(long)); ! 190: goto close_fd; ! 191: } ! 192: ! 193: /* ! 194: * Seek and patch. ! 195: */ ! 196: seek = sym->n_value; ! 197: /* ! 198: * Adjust the file offset for the symbol based on which ! 199: * segment it resides in. ! 200: */ ! 201: if (sym->n_scnum == text_scnum) { ! 202: seek = (seek - text_addr) + text_base; ! 203: } else if (sym->n_scnum == data_scnum) { ! 204: seek = (seek - data_addr) + data_base; ! 205: } else { ! 206: fprintf(stderr, "Bad section number!!.\n"); ! 207: goto close_fd; ! 208: } ! 209: ! 210: sought = lseek(fd, seek, 0); ! 211: if (sought == -1) { ! 212: fprintf(stderr, "asypatch: lseek to %x failed\n", seek); ! 213: } ! 214: ! 215: /* if (xflag) ! 216: * printf("write(%d, [%x]=%x, %d)->%x\n", ! 217: * fd, buf, *(int*)buf, len, sought); ! 218: */ ! 219: if (do_read) { ! 220: if ((rwct = read(fd, buf, len)) != len) { ! 221: fprintf(stderr, "asypatch %s: read %d bytes of %d\n", ! 222: stbl, rwct, len); ! 223: goto close_fd; ! 224: } ! 225: } else { ! 226: if ((rwct = write(fd, buf, len)) != len) { ! 227: fprintf(stderr, "asypatch %s: wrote %d bytes of %d\n", ! 228: stbl, rwct, len); ! 229: goto close_fd; ! 230: } ! 231: } ! 232: ret = 1; ! 233: ! 234: close_fd: ! 235: close(fd); ! 236: no_close_fd: ! 237: return ret; ! 238: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.