Example #1
0
int hide_aout(int inf, const char *filename)
{
    struct stat infstat;
    struct relocation_info *relp;
    struct nlist *symp;
    int rc;

    /*
     * do some error checking.
     */

    if(fstat(inf, &infstat) == -1) {
	perror(filename);
	return 1;
    }

    /*
     * Read the entire file into memory.  XXX - Really, we only need to
     * read the header and from TRELOFF to the end of the file.
     */

    if((aoutdata = (char *) malloc(infstat.st_size)) == NULL) {
	fprintf(stderr, "%s: too big to read into memory\n", filename);
	return 1;
    }

    if((rc = read(inf, aoutdata, infstat.st_size)) < infstat.st_size) {
	fprintf(stderr, "%s: read error: %s\n", filename,
		rc == -1? strerror(errno) : "short read");
	return 1;
    }

    /*
     * Calculate offsets and sizes from the header.
     */

    hdrp = (struct exec *) aoutdata;

#ifdef __FreeBSD__
    textrel = (struct relocation_info *) (aoutdata + N_RELOFF(*hdrp));
    datarel = (struct relocation_info *) (aoutdata + N_RELOFF(*hdrp) +
					  hdrp->a_trsize);
#else
    textrel = (struct relocation_info *) (aoutdata + N_TRELOFF(*hdrp));
    datarel = (struct relocation_info *) (aoutdata + N_DRELOFF(*hdrp));
#endif
    symbase = (struct nlist *)		 (aoutdata + N_SYMOFF(*hdrp));
    strbase = (char *) 			 (aoutdata + N_STROFF(*hdrp));

    ntextrel = hdrp->a_trsize / sizeof(struct relocation_info);
    ndatarel = hdrp->a_drsize / sizeof(struct relocation_info);
    nsyms    = hdrp->a_syms   / sizeof(struct nlist);

    /*
     * Zap the type field of all globally-defined symbols.  The linker will
     * subsequently ignore these entries.  Don't zap any symbols in the
     * keep list.
     */

    for(symp = symbase; symp < symbase + nsyms; symp++) {
	if(!IS_GLOBAL_DEFINED(symp))		/* keep undefined syms */
	    continue;

	/* keep (C) symbols which are on the keep list */
	if(SYMSTR(symp)[0] == '_' && in_keep_list(SYMSTR(symp) + 1))
	    continue;

	symp->n_type = 0;
    }

    /*
     * Check whether the relocation entries reference any symbols that we
     * just zapped.  I don't know whether ld can handle this case, but I
     * haven't encountered it yet.  These checks are here so that the program
     * doesn't fail silently should such symbols be encountered.
     */

    for(relp = textrel; relp < textrel + ntextrel; relp++)
	check_reloc(filename, relp);
    for(relp = datarel; relp < datarel + ndatarel; relp++)
	check_reloc(filename, relp);

    /*
     * Write the .o file back out to disk.  XXX - Really, we only need to
     * write the symbol table entries back out.
     */
    lseek(inf, 0, SEEK_SET);
    if((rc = write(inf, aoutdata, infstat.st_size)) < infstat.st_size) {
	fprintf(stderr, "%s: write error: %s\n", filename,
		rc == -1? strerror(errno) : "short write");
	return 1;
    }

    return 0;
}
Example #2
0
void 
hide_syms(char *filename)
{
	int             inf, outf, rc;
	struct stat     infstat;
	struct relocation_info *relp;
	struct nlist   *symp;
	char           *buf;
	u_char          zero = 0;

	/*
         * Open the file and do some error checking.
         */

	if ((inf = open(filename, O_RDWR)) == -1) {
		perror(filename);
		return;
	}
	if (fstat(inf, &infstat) == -1) {
		perror(filename);
		close(inf);
		return;
	}
	if (infstat.st_size < sizeof(struct exec)) {
		fprintf(stderr, "%s: short file\n", filename);
		close(inf);
		return;
	}
	if ((buf = mmap(NULL, infstat.st_size, PROT_READ | PROT_WRITE,
	    MAP_FILE | MAP_SHARED, inf, 0)) == MAP_FAILED) {
		fprintf(stderr, "%s: cannot map\n", filename);
		close(inf);
		return;
	}

#ifdef _NLIST_DO_ELF
	if (buf[0] == 0x7f && (buf[1] == 'E' || buf[1] == 'O') &&
	    buf[2] == 'L' && buf[3] == 'F') {
		elf_hide(inf, buf);
		return;
	}
#endif				/* _NLIST_DO_ELF */

#ifdef _NLIST_DO_ECOFF
	if (!ECOFF_BADMAG((struct ecoff_exechdr *) buf)) {
		ecoff_hide(inf, buf);
		return;
	}
#endif				/* _NLIST_DO_ECOFF */

#ifdef DO_AOUT
	aoutdata = buf;

	/*
         * Check the header and calculate offsets and sizes from it.
         */
	hdrp = (struct exec *) aoutdata;

	if (N_BADMAG(*hdrp)) {
		fprintf(stderr, "%s: bad magic: not an a.out, ecoff or elf  file\n",
		    filename);
		close(inf);
		return;
	}
	textrel = (struct relocation_info *) (aoutdata + N_TRELOFF(*hdrp));
	datarel = (struct relocation_info *) (aoutdata + N_DRELOFF(*hdrp));
	symbase = (struct nlist *) (aoutdata + N_SYMOFF(*hdrp));
	strbase = (char *) (aoutdata + N_STROFF(*hdrp));

	ntextrel = hdrp->a_trsize / sizeof(struct relocation_info);
	ndatarel = hdrp->a_drsize / sizeof(struct relocation_info);
	nsyms = hdrp->a_syms / sizeof(struct nlist);

	/*
         * Zap the type field of all globally-defined symbols.  The linker will
         * subsequently ignore these entries.  Don't zap any symbols in the
         * keep list.
         */
	for (symp = symbase; symp < symbase + nsyms; symp++)
		if (IS_GLOBAL_DEFINED(symp) && !in_keep_list(SYMSTR(symp))) {
			/*
		         * XXX Our VM system has some problems, so
		         * avoid the VM system....
		         */
			lseek(inf, (off_t) ((void *) &symp->n_type -
			    (void *) buf), SEEK_SET);
			write(inf, &zero, sizeof zero);
			symp->n_type = 0;
		}
	/*
         * Check whether the relocation entries reference any symbols that we
         * just zapped.  I don't know whether ld can handle this case, but I
         * haven't encountered it yet.  These checks are here so that the program
         * doesn't fail silently should such symbols be encountered.
         */
	for (relp = textrel; relp < textrel + ntextrel; relp++)
		check_reloc(filename, relp);
	for (relp = datarel; relp < datarel + ndatarel; relp++)
		check_reloc(filename, relp);

	msync(buf, infstat.st_size, MS_SYNC);
	munmap(buf, infstat.st_size);
	close(inf);
#endif				/* DO_AOUT */
}