|
|
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.