示例#1
0
qboolean Rank_OpenRankings(void)
{
	char syspath[MAX_OSPATH];
	size_t result;
	qboolean created;
	if (!rankfile)
	{
		if (!*rank_filename.string)
		{
			return false;
		}

		if (!FS_NativePath(rank_filename.string, FS_GAMEONLY, syspath, sizeof(syspath)))
			return false;

		rankfile = FS_OpenVFS(rank_filename.string, "r+b", FS_GAMEONLY);
		if (!rankfile)	//hmm... try creating
		{
			rankfile = FS_OpenVFS(rank_filename.string, "w+b", FS_GAMEONLY);
			created = true;
		}
		else
			created = false;
		if (!rankfile)
			return false;	//couldn't open file.

		memset(&rankfileheader, 0, sizeof(rankfileheader));

		VFS_SEEK(rankfile, 0);
		result = VFS_READ(rankfile, &rankfileheader, sizeof(rankfileheader_t));

		if (result != sizeof(rankfileheader_t))
			Con_Printf("Rank_OpenRankings() fread: expected %lu, result was %u (%s)\n",(long unsigned int)sizeof(rankfileheader_t),(unsigned int)result, rank_filename.string);

		rankfileheader.version		= swaplong(rankfileheader.version);
		rankfileheader.usedslots	= swaplong(rankfileheader.usedslots);
		rankfileheader.leader		= swaplong(rankfileheader.leader);
		rankfileheader.freeslot		= swaplong(rankfileheader.freeslot);

		if (!created && (rankfileheader.version != RANKFILE_VERSION || rankfileheader.ident != RANKFILE_IDENT))
		{
			Con_Printf("Rank file is version %i not %i\nEither delete the file or use an equivelent version of " FULLENGINENAME "\n", rankfileheader.version, RANKFILE_VERSION);
			VFS_CLOSE(rankfile);
			rankfile = NULL;

			return false;
		}

		return true;	//success.
	}
	return true;	//already open
}
示例#2
0
static void WRITEHEADER(void)
{
	rankfileheader_t nh;

	nh.ident		= RANKFILE_IDENT;
	nh.version		= swaplong(RANKFILE_VERSION);
	nh.usedslots	= swaplong(rankfileheader.usedslots);
	nh.leader		= swaplong(rankfileheader.leader);
	nh.freeslot		= swaplong(rankfileheader.freeslot);

	VFS_SEEK(rankfile, 0);
	VFS_WRITE(rankfile, &nh, sizeof(rankfileheader_t));
}
示例#3
0
static void WRITE_PLAYERHEADER(int x, rankheader_t *oh)
{
	rankheader_t nh;

	VFS_SEEK(rankfile, sizeof(rankfileheader_t)+((x-1)*sizeof(rankinfo_t)));

	nh.prev = swaplong(oh->prev);		//score is held for convineance.
	nh.next = swaplong(oh->next);
	Q_strncpyz(nh.name, oh->name, sizeof(nh.name));
	nh.pwd = swaplong(oh->pwd);
	nh.score = swapfloat(oh->score);

	VFS_WRITE(rankfile, &nh, sizeof(rankheader_t));
}
示例#4
0
static int prcparse(UBYTE *prcfile,size_t_68k prcsize){
	palmdb meep;
	meep.numrecords = prcfile[0x4C] << 8 | prcfile[0x4C + 1];

	memcpy(meep.name,prcfile,32);

	memcpy(&meep.flags,prcfile + 0x20,2);
	swapword(meep.flags);
	memcpy(&meep.version,prcfile + 0x22,2);
	swapword(meep.version);
	memcpy(&meep.modnum,prcfile + 0x30,4);
	swaplong(meep.modnum);
	memcpy(&meep.appinfo,prcfile + 0x34,4);
	swaplong(meep.appinfo);
	memcpy(&meep.sortinfo,prcfile + 0x38,4);
	swaplong(meep.sortinfo);

	memcpy(meep.type.typec,prcfile + 0x3C,4);
	memcpy(meep.creator.typec,prcfile + 0x40,4);

	memcpy(&meep.uuidseed,prcfile + 0x44,4);
	swaplong(meep.uuidseed);
	memcpy(&meep.nextrecordlist,prcfile + 0x48,4);
	swaplong(meep.nextrecordlist);

	//get the needed 68k memory
	curmemloc = getnewlinearchunks(NUM_BANKS(prcsize + meep.numrecords * 4)) << 16;
	if(curmemloc != 0){
		avbytes = NUM_BANKS(prcsize + meep.numrecords * 4) * SIZEOFBANK;
		currealaddr = (UBYTE*)get_real_address(curmemloc);
	}
	else return FAILEDMALLOC;

	meep.open = false;
	meep.resdb = true;

	apps.push_back(meep);
	unsigned int robin;
	for(robin = 0;robin < meep.numrecords;robin++){
		unpackprcresource(robin,prcfile,prcsize,apps.size() - 1);
	}

	apps[apps.size() - 1].intmain = getresource(apps.size() - 1,1,'code');
	if(apps[apps.size() - 1].intmain != 0){
		apps[apps.size() - 1].exe = true;
		hasbootableapp = true;
	}

	return WORKED;
}
示例#5
0
static void READ_PLAYERHEADER(int x, rankheader_t *oh)
{
	size_t result;

	VFS_SEEK(rankfile, sizeof(rankfileheader_t)+((x-1)*sizeof(rankinfo_t)));

	result = VFS_READ(rankfile, oh, sizeof(rankheader_t));

	if (result != sizeof(rankheader_t))
		Con_Printf("READ_PLAYERHEADER() fread: expected %lu, result was %u\n",(long unsigned int)sizeof(rankheader_t),(unsigned int)result);

	oh->prev = swaplong(oh->prev);		//score is held for convineance.
	oh->next = swaplong(oh->next);
//	strcpy(oh->name, oh->name);
	oh->pwd = swaplong(oh->pwd);
	oh->score = swapfloat(oh->score);
}
示例#6
0
static CTL_MSG
swapmsg(CTL_MSG req)
{
	CTL_MSG swapreq;

	if (req.ctl_addr.sin_family == swapshort(AF_INET)) {
		swapreq = req;
		swapreq.id_num = swaplong(req.id_num);
		swapreq.pid = swaplong(req.pid);
		swapreq.addr.sin_family = swapshort(req.addr.sin_family);
		swapreq.ctl_addr.sin_family =
			swapshort(req.ctl_addr.sin_family);
		return (swapreq);
	} else {
		return (req);
	}
}
示例#7
0
static void WRITE_PLAYERSTATS(int x, rankstats_t *os)
{
	rankstats_t ns;
	int i;

	VFS_SEEK(rankfile, sizeof(rankfileheader_t)+sizeof(rankheader_t)+((x-1)*sizeof(rankinfo_t)));

	ns.kills = swaplong(os->kills);
	ns.deaths = swaplong(os->deaths);
	for (i = 0; i < NUM_RANK_SPAWN_PARMS; i++)
		ns.parm[i] = swapfloat(os->parm[i]);
	ns.timeonserver = swapfloat(os->timeonserver);
	ns.flags1 = (os->flags1);
	ns.trustlevel = (os->trustlevel);
	ns.pad2 = (os->pad2);
	ns.pad3 = (os->pad3);

	VFS_WRITE(rankfile, &ns, sizeof(rankstats_t));
}
示例#8
0
static void READ_PLAYERSTATS(int x, rankstats_t *os)
{
	int i;
	size_t result;

	VFS_SEEK(rankfile, sizeof(rankfileheader_t)+sizeof(rankheader_t)+((x-1)*sizeof(rankinfo_t)));
	result = VFS_READ(rankfile, os, sizeof(rankstats_t));

	if (result != sizeof(rankstats_t))
		Con_Printf("READ_PLAYERSTATS() fread: expected %lu, result was %u\n",(long unsigned int)sizeof(rankstats_t),(unsigned int)result);

	os->kills = swaplong(os->kills);
	os->deaths = swaplong(os->deaths);
	for (i = 0; i < NUM_RANK_SPAWN_PARMS; i++)
		os->parm[i] = swapfloat(os->parm[i]);
	os->timeonserver = swapfloat(os->timeonserver);
//	os->flags1 = (os->flags1);
//	os->trustlevel = (os->trustlevel);
//	os->pad2 = (os->pad2);
//	os->pad3 = (os->pad3);
}
示例#9
0
/*
   basic opening of WAD file and creation of node in Wad linked list
*/
WadPtr BasicWadOpen( char *filename)
{
   WadPtr curw, prevw;

   /* find the WAD file in the Wad file list */
   prevw = WadFileList;
   if (prevw)
   {
      curw = prevw->next;
      while (curw && strcmp( filename, curw->filename))
      {
	 prevw = curw;
	 curw = prevw->next;
      }
   }
   else
      curw = NULL;

   /* if this entry doesn't exist, add it to the WadFileList */
   if (! curw)
   {
      curw = (WadPtr) GetMemory( sizeof( struct WadFileInfo));
      if (! prevw)
	 WadFileList = curw;
      else
	 prevw->next = curw;
      curw->next = NULL;
      curw->filename = filename;
   }

   /* open the file */
   if ((curw->fileinfo = fopen( filename, "rb")) == NULL)
   {
      if (! prevw)
	 WadFileList = NULL;
      else
	 prevw->next = curw->next;
      FreeMemory( curw);
      ProgError( "error opening \"%s\"", filename);
   }

   /* read in the WAD directory info */
   BasicWadRead( curw, curw->type, 4);
   if (strncmp( curw->type, "IWAD", 4) && strncmp( curw->type, "PWAD", 4))
      ProgError( "\"%s\" is not a valid WAD file", filename);
   BasicWadRead( curw, &curw->dirsize, sizeof( curw->dirsize));
   swaplong( &(curw->dirsize));
   BasicWadRead( curw, &curw->dirstart, sizeof( curw->dirstart));
   swaplong( &(curw->dirstart));

   /* read in the WAD directory itself */
   curw->directory = (DirPtr) GetMemory( sizeof( struct Directory) * curw->dirsize);
   BasicWadSeek( curw, curw->dirstart);
   BasicWadRead( curw, curw->directory, sizeof( struct Directory) * curw->dirsize);
#ifdef BIGEND
   {
     int i;
     for (i = 0; i < curw->dirsize; i++)
     {
        DirPtr d = &(curw->directory[ i]);
        swaplong( &(d->start));
        swaplong( &(d->size));
     }
   }
#endif

   /* all done */
   return curw;
}
示例#10
0
void decompile(wadfile_t *wf, int num)
{
  	char		name[9];
	unsigned char	*sprite;
	short		width;
	short		height;
	short		xoff;
	short		yoff;
	short		*p1;
	int		*columns;
	unsigned char	*post;
	int		x;
	int		y;
	int		n;
	int		i;

	name[0] = '\0';
	strncat(name, wf->lp->lumps[num]->name, 8);

	/* get sprite lump */
	if ((sprite = (unsigned char *)get_lump_by_num(wf, num)) == NULL) {
		fprintf(stderr, "can't find sprite lump %s\n", name);
		exit(1);
	}

	/* clear the pixel buffer */
	memset(img_buf, 255, 320 * 200);

	/* get width, height and offsets from the lump header */
	p1 = (short *) sprite;
	width = *p1++;
	swapint(&width);
	height = *p1++;
	swapint(&height);
	xoff = *p1++;
	swapint(&xoff);
	yoff = *p1++;
	swapint(&yoff);
	
	printf("  got sprite %s, width=%d, height=%d\n", name,
		width, height);

	/* copy picture data into pixel buffer */
	columns = (int *) (sprite + 8);
	for (x = 0; x < width; x++) {
	  swaplong(&columns);
	  post = sprite + *columns++;
	  y = (int) *post++;
	  while (y != 255) {
	    n = (int) *post++;
	    post++;	/* first byte unused */
	    for (i = 0; i < n; i++) {
		img_buf[(y+i) * width + x] = *post;
		post++;
	    }
	    post++;	/* last byte unused */
	    y = (int) *post++;
	  }
	}

	/* free sprite lump memory */
	free(sprite);

	/* write image buffer into ppm file */
	write_ppm(name, width, height);
}
示例#11
0
/*
 *	list_wad - list the contents of one wad file
 */
static int list_wad(const char *file)
{
	wadinfo_t	wad_header;
	filelump_t	lump;
	FILE		*fp;
	int		list_flats = 0;
	int		i, j;
	int		n, m;
	int		toff;
	char		name[9];
	long		old_off, tex_off, sav_off;

	/* try to open WAD file */
        if ((fp = fopen(file, "rb")) == NULL) {
                err(file, "can't open (%s)", strerror (errno));
                return 1;
        }

	/* read WAD file header */
	if (fread((void *)&wad_header, sizeof(wadinfo_t), 1, fp) != 1) {
		err(file, "can't read WAD header");
		return 1;
	}
	swaplong(&(wad_header.numlumps));
	swaplong(&(wad_header.infotableofs));

	/* is this a WAD file? */
	if (strncmp(wad_header.identification, "IWAD", 4) &&
	    strncmp(wad_header.identification, "PWAD", 4)) {
		err(file, "not a WAD file");
		return 1;
	}

	if (verbose) {
		printf("WAD type = %c%c%c%c\n", wad_header.identification[0],
			wad_header.identification[1],
			wad_header.identification[2],
			wad_header.identification[3]);
		printf("no. of lumps: %d\n", wad_header.numlumps);
		printf("directory offset: %d\n", wad_header.infotableofs);
	}

	/* now seek to the directory */
	if (fseek(fp, (long)wad_header.infotableofs, SEEK_SET) == -1) {
		err(file, "can't seek to directory");
		return 1;
	}

	/* now read the directory entries */
	for (i = 0; i < wad_header.numlumps; i++) {
		if (fread((void *)&lump, sizeof(filelump_t), 1, fp) != 1) {
			err(file, "can't read lump directory entry");
			return 1;
		}
		swaplong(&(lump.filepos));
		swaplong(&(lump.size));

		/* list contents of PNAMES lump? */
		if (pflag) {
		  if (strncmp(&lump.name[0], "PNAMES", 6)) {
		    continue;
		  } else {
		    if (verbose) {
		      printf("\nContents of PNAMES:\n");
		    }
		    if (fseek(fp, (long)lump.filepos, SEEK_SET) == -1) {
			    err(file, "can't seek to PNAMES");
			    return 1;
		    }
		    n = getlong(fp);
		    memset(&name[0], 0, 9);
		    for (i = 0; i < n; i++) {
		      fread((void *)&name[0], 8, 1, fp);
		      printf("%s\n", &name[0]);
		    }
		    break;
		  }

		/* list contents of TEXTUREx lumps? */
		} else if (tflag) {
		  if (strncmp(&lump.name[0], "TEXTURE1", 8) &&
		      strncmp(&lump.name[0], "TEXTURE2", 8)) {
			continue;
		  } else {
		    old_off = ftell(fp);
		    memset(&name[0], 0, 9);
		    strncpy(&name[0], &lump.name[0], 8);
		    if (verbose) {
		      printf("\nContents of %s:\n", &name[0]);
		    }
		    if (fseek(fp, (long)lump.filepos, SEEK_SET) == -1) {
			    err(file, "can't seek to %s", file, &name[0]);
			    return 1;
		    }
		    tex_off = ftell(fp);
		    n = getlong(fp);
		    for (j = 0; j < n; j++) {
		      toff = getlong(fp);
		      sav_off = ftell(fp);
		      if (fseek(fp, tex_off + toff, SEEK_SET) == -1) {
			err(file, "can't seek to texture");
			return 1;
		      }
		      fread((void *)&name[0], 8, 1, fp);
		      printf("%s", &name[0]);
		      if (lstflag) {
			m = getshort(fp);	/* always 0 */
			m = getshort(fp);	/* always 0 */
			m = getshort(fp);	/* width */
			printf("\t%d", (int)m);
			m = getshort(fp);	/* height */
			printf("\t%d", (int)m);
			m = getshort(fp);	/* always 0 */
			m = getshort(fp);	/* always 0 */
			m = getshort(fp);	/* number of patches */
			printf("\t%d", (int)m);
		      }
		      putchar('\n');
		      fseek(fp, sav_off, SEEK_SET);
		    }
		    fseek(fp, old_off, SEEK_SET);
		  }

		/* list flats between F_START and F_END? */
		} else if (fflag) {
		  if (!strncmp(&lump.name[0], "F_START", 7)) {
			list_flats = 1;
			continue;
		  } else if (!strncmp(&lump.name[0], "F_END", 5)) {
			list_flats = 0;
			break;
		  } else {
			if (list_flats && (lump.size > 0)) {
				print_name(&lump.name[0]);
				putchar('\n');
			}
		  }

		/* list contents of the whole WAD file */
		} else {
		  print_name(&lump.name[0]);
		  if (lstflag || sflag) {
		  	if (kflag) {
				printf("\t%8d", (lump.size + 512) / 1024);
			} else if (Hflag) {
				printf("\t%08Xh", lump.size);
			} else {
				printf("\t%8d", lump.size);
			}
		  }
		  if (lstflag) {
			if (hflag) {
		  		printf("\t%08Xh", lump.filepos);
			} else {
				printf("\t%8d", lump.filepos);
			}
		  }
		  putchar('\n');
		}
	}

	return 0;
}
示例#12
0
CPWad::CPWad (XString name)
      : file (name, O_RDWR | O_BINARY), currentmap(0)
{
     if (file.IsOpen())
     {
          // -=- read the pwad header -=-
          cout << "Opened '" << name << "'" << endl;
          cdebug.out << "Opened '" << name << "'" << endl;
          file.Read (&header, sizeof(PWAD_HEADER));
          swaplong((int *)&(header.dir_offset));
          swaplong((int *)&(header.dir_entries));
          if (memcmp ("PWAD", header.signature, 4) != 0)
          {
               cout << "Not a PWAD!" << "\n";
               cdebug.out << "Not a PWAD!" << "\n";
               Fail ();
               return;
          }
          else
          {
               cdebug.out << "File size: " << file.Size() << endl;
               cdebug.out << "Directory Offset: " << header.dir_offset << endl;
               cdebug.out << "Directory Entries: " << header.dir_entries << endl;
          }

          // -=- read the directory -=-
          file.Seek (header.dir_offset);
          MemHandle dirbuff = file.Read ((size_t)(header.dir_entries * sizeof(DIR_ENTRY)));
          if (dirbuff.Size () != (header.dir_entries * sizeof(DIR_ENTRY)))
          {
               cout << "Error Reading PWAD Directory." << endl;
               cdebug.out << "Error Reading PWAD Directory." << endl;
               Fail ();
          }
          else
          {
               cout << "Building directory...." << flush;
               swap_lump_list((void *)dirbuff.Buffer(), header.dir_entries);
               // -=- go through each dir entry and add it to our internal dir -=-
               DIR_ENTRY *entry_ptr = (DIR_ENTRY *)dirbuff.Buffer();
               
               for (int n = 0; n < header.dir_entries; n++)
               {
                    AddEntry (entry_ptr[n]);
               }
               cout << "Done." << endl;

// -=- print out directory used for debugging -=- 
               CDirEntry *de;
               CDirEntry *sde;
               de = (CDirEntry *)directory.FirstItem ();
               while (de)
               {
                    cdebug.out << de->GetKey() << "  " << de->Size() << " bytes\t  @" << de->Offset() << endl;
                    sde = (CDirEntry *)de->subdir.FirstItem ();
                    while (sde)
                    {
                         cdebug.out << "  " << sde->GetKey() << "  "  << sde->Size() << " bytes\t  @" << sde->Offset() << endl;
                         sde = (CDirEntry *)sde->Next();
                    }

                    de = (CDirEntry *)de->Next();
               }
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
          }
     }
     else
     {
          cout << "Cannot open '" << name << "'" << endl;
          cdebug.out << "Cannot open '" << name << "'" << endl;
          Fail ();
     }
}
示例#13
0
/**
 * @brief Copy the PLT of an ET_EXEC object for the ALTPLT technique.
 * and the GOT of an ET_EXEC object for the ALTGOT technique.
 * @param file Host file.
 * @param mod Always inject sections with size being a multiple of mod.
 * @return Success (0) or Error (-1).
 */
int		elfsh_relink_plt(elfshobj_t *file, u_int mod)
{
    elfshsect_t	*got;
    elfshsect_t   *plt;
    elfshsect_t	*symtab;
    elfshsect_t	*dynsym;
    elfshsect_t	*prolog;
    elfshsect_t	*extplt = NULL;
    elfshsect_t	*altgot = NULL; /* shut the nice talkative */
    elfshsect_t	*enew    = NULL; /* compiler also know as gcc */
    elfsh_Shdr	hdr;
    elfsh_Sym	*sym;
    elfsh_Sym	newsym;
    char		buf[BUFSIZ];
    u_int		off;
    u_int		entsz;
    int		mode;
    eresi_Addr	addr;
    char		*prologdata;
    u_int		sz;
    char		*name;
    u_char	ostype;
    eresi_Addr	diff;
    u_int		extplt_size;

    PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

    /* Get PLT */
    if (file->secthash[ELFSH_SECTION_ALTPLT] != NULL)
        PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
    plt = elfsh_get_plt(file, NULL);
    if (NULL == plt)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "PLT section not found", -1);
    entsz = elfsh_get_pltentsz(file);
    if (entsz < 0)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Failed to get PLT entry size", -1);

    /* Get GOT (recent ld call it .got.plt) */
    got = elfsh_get_gotsct(file);
    if (NULL == got)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "GOT section not found", -1);

    /* Get symtabs */
    if (NULL == elfsh_get_dynsymtab(file, NULL))
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "DYNSYM not found", -1);
    if (NULL == elfsh_get_symtab(file, NULL))
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "SYMTAB not found", -1);

    /* Some fingerprint */
    ostype = elfsh_get_ostype(file);
    if (ostype == ELFSH_OS_ERROR)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Invalid OS target", -1);

    /* Insert alternative .plt */
    dynsym = file->secthash[ELFSH_SECTION_DYNSYM];
    symtab = file->secthash[ELFSH_SECTION_SYMTAB];

    /* FreeBSD and BeoS is incompatible with pre-interp injection */
    /* Solaris needs self-mutating code for ALTPLT technique */
    /* %gp offsets on ALPHA/MIPS requires data injection */
    ELFSH_SELECT_INJECTION(file,NULL,mode);

    /* Map .alt.plt.prolog on ALPHA, or .alt.got.prolog on MIPS */
    if (FILE_IS_MIPS(file) || FILE_IS_ALPHA64(file))
    {
        if (FILE_IS_MIPS(file))
        {
            name = ELFSH_SECTION_NAME_ALTGOTPROLOG;
            sz = 28;
        }
        else
        {
            name = ELFSH_SECTION_NAME_ALTPLTPROLOG;
            sz = 48;
        }
        prolog = elfsh_create_section(name);
        hdr = elfsh_create_shdr(0, SHT_PROGBITS, SHF_EXECINSTR | SHF_ALLOC,
                                0, 0, sz, 0, 0, 0, 0);

        XALLOC(__FILE__, __FUNCTION__, __LINE__, prologdata, sz, -1);

        if (elfsh_insert_mapped_section(file,
                                        prolog, hdr, prologdata,
                                        mode, mod) < 0)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         ".alt.{plt,got}.prolog insertion failed", -1);

        enew = elfsh_get_section_by_name(file, name, NULL, NULL, NULL);
        if (enew == NULL)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         ".alt.{plt,got}.prolog insertion failed", -1);
        file->secthash[ELFSH_SECTION_ALTPLTPROLOG] = enew;
    }

    /* Map .alt.plt (or .pad.got on MIPS)

       On MIPS we use .pad.got in order to align .alt.got on a 0x1000
       bound boundary.

       On ALPHA and SPARC, .alt.plt will be relocated instead of .plt
    */
    sz = plt->shdr->sh_size;
    if (FILE_IS_MIPS(file))
    {
        addr = enew->shdr->sh_addr + enew->shdr->sh_size;
        if ((addr - (got->shdr->sh_addr)) % 1024)
            sz = 1024 - ((addr - (got->shdr->sh_addr)) % 1024);
        XALLOC(__FILE__, __FUNCTION__, __LINE__, prologdata, sz, -1);
        memset(prologdata, 0x00, sz);
        name = ELFSH_SECTION_NAME_PADGOT;
    }
    else
    {
        XALLOC(__FILE__, __FUNCTION__, __LINE__, prologdata, sz, -1);
        memcpy(prologdata, elfsh_readmem(plt), sz);
        name = ELFSH_SECTION_NAME_ALTPLT;
    }
    enew = elfsh_create_section(name);
    hdr = elfsh_create_shdr(0, SHT_PROGBITS, SHF_EXECINSTR | SHF_ALLOC,
                            0, 0, sz, 0, 0, 0, 0);
    if (elfsh_insert_mapped_section(file, enew, hdr, prologdata, mode, mod) < 0)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     ".alt.plt|.pad.got insertion failed", -1);
    enew = elfsh_get_section_by_name(file, name, NULL, NULL, NULL);
    if (enew == NULL)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     ".alt.plt|.pad.got insertion failed", -1);
    file->secthash[ELFSH_SECTION_ALTPLT] = enew;


    /* Map .alt.got (all architectures except SPARC) */
    /* On IA32, remap GOT with a doubled size for non-present symbol resolving */
    if (FILE_IS_MIPS(file) || FILE_IS_ALPHA64(file) || FILE_IS_IA32(file))
    {
        sz = (FILE_IS_MIPS(file) ? got->shdr->sh_size     :
              FILE_IS_IA32(file) ? got->shdr->sh_size * 4 :
              plt->shdr->sh_size / elfsh_get_pltentsz(file) * sizeof(eresi_Addr));

        altgot = elfsh_create_section(ELFSH_SECTION_NAME_ALTGOT);
        hdr = elfsh_create_shdr(0, SHT_PROGBITS, SHF_ALLOC | SHF_WRITE,
                                0, 0, sz, 0, 0, 0, sizeof(eresi_Addr));

        XALLOC(__FILE__, __FUNCTION__, __LINE__, prologdata, sz, -1);
        memcpy(prologdata, elfsh_readmem(got), got->shdr->sh_size);

        if (elfsh_insert_mapped_section(file, altgot, hdr, prologdata,
                                        ELFSH_DATA_INJECTION, mod) < 0)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         ".alt.got insertion failed", -1);

        altgot = elfsh_get_section_by_name(file, ELFSH_SECTION_NAME_ALTGOT,
                                           NULL, NULL, NULL);
        if (altgot == NULL)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         ".alt.got insertion failed", -1);
        file->secthash[ELFSH_SECTION_ALTGOT] = altgot;
        altgot->curend = got->shdr->sh_size;
        memset(elfsh_readmem(altgot) + got->shdr->sh_size, 0x00, got->shdr->sh_size);
        altgot->shdr->sh_entsize = sizeof(eresi_Addr);
    }


    /* Insert EXTPLT in order to be able to resolve non present symbols */
    if (FILE_IS_IA32(file))
    {
        extplt_size = plt->shdr->sh_size * 2;
        extplt = elfsh_create_section(ELFSH_SECTION_NAME_EXTPLT);
        hdr = elfsh_create_shdr(0, SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR,
                                0, 0, extplt_size, 0, 0, 0, 0);

        XALLOC(__FILE__, __FUNCTION__, __LINE__, prologdata, plt->shdr->sh_size, -1);
        memcpy(prologdata, elfsh_readmem(plt), plt->shdr->sh_size);

        if (elfsh_insert_mapped_section(file, extplt, hdr, prologdata,
                                        mode, mod) < 0)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         ".ext.plt insertion failed", -1);
        extplt = elfsh_get_section_by_name(file, ELFSH_SECTION_NAME_EXTPLT,
                                           NULL, NULL, NULL);
        if (extplt == NULL)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         ".ext.plt insertion failed", -1);
        file->secthash[ELFSH_SECTION_EXTPLT] = extplt;
        extplt->curend = elfsh_get_first_pltentsz(file);
    }



    /* Loop on .plt and inject 'old_symnam' symbols */
    for (off = 0; off < plt->shdr->sh_size; off += entsz)
    {

        /* SPARC does not have ALTGOT */
        if (FILE_IS_MIPS(file) || FILE_IS_ALPHA64(file) || FILE_IS_IA32(file))
            diff = (uint32_t) altgot->shdr->sh_addr - got->shdr->sh_addr;
        else
            diff = 0;

        /* Special case for the first plt entry */
        if (off == 0 && elfsh_altplt_firstent(enew, &off, symtab, file, extplt, plt, diff) < 0)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         "ALTPLT on first entry failed", -1);
        else if (off == 0)
            continue;

        /* Get the existing symbol name for this plt entry ... */
        sym = elfsh_get_sym_by_value(elfsh_readmem(dynsym),
                                     dynsym->shdr->sh_size / sizeof(elfsh_Sym),
                                     plt->shdr->sh_addr + off,
                                     NULL, ELFSH_EXACTSYM);

        /* New versions of ld do not fill the vaddr of dynamic symbols,
        do it ourself. Do not insert old symbol in emergency cases */
        if (sym == NULL)
        {
            if ((sym = elfsh_restore_dynsym(file, plt, off, dynsym)) == NULL)
                continue;

            name = elfsh_get_dynsymbol_name(file, sym);

            /* __gmon_start__ should not be resolved
               if it was not already done by gcc */
            if (name && !strcmp(name, "__gmon_start__"))
                sym->st_value = 0x0;
        }

        /* ... and we inject the 'old' occurence symbol pointing in
        .alt.plt (.plt on MIPS) */
        if (!FILE_IS_MIPS(file))
            addr = enew->shdr->sh_addr + off;
        else
            addr = plt->shdr->sh_addr + off;

#if   __BYTE_ORDER == __BIG_ENDIAN
        if (file->hdr->e_ident[EI_DATA] == ELFDATA2LSB)
#elif __BYTE_ORDER == __LITTLE_ENDIAN
        if (file->hdr->e_ident[EI_DATA] == ELFDATA2MSB)
#else
#error Unexpected __BYTE_ORDER !
#endif
            addr = swaplong(addr);

        /* Injection */
        name = elfsh_get_dynsymbol_name(file, sym);
        newsym = elfsh_create_symbol(addr, entsz, STT_FUNC, 0, 0, 0);
        snprintf(buf, BUFSIZ, "old_%s", name);
        if (elfsh_insert_symbol(symtab, &newsym, buf) < 0)
            PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                         "old_* symbol injection failed", -1);

#if __DEBUG_COPYPLT__
        printf("[DEBUG_COPYPLT] Symbol at .plt + %u injected"
               " succesfully (%s) \n", off, buf);
#endif

        /* On ALPHA, shift the relocation offset from .got to .alt.got to avoid
        hooks removing when calling back the original function. */
        if (FILE_IS_ALPHA64(file) &&
                elfsh_shift_alpha_relocs(file, name, altgot, off) < 0)
            continue;

        /* Reencode the PLT entry to use the alternative GOT */
        /* This condition is for compatibility with other archs where EXTPLT
        is not yet supported. For those we do not enter the hook */
        if (FILE_IS_IA32(file))
        {
            diff = (eresi_Addr) altgot->shdr->sh_addr - got->shdr->sh_addr;
            elfsh_encodeplt(file, plt, diff, off);
            if (file->hdr->e_type == ET_DYN)
                elfsh_encodeplt(file, file->secthash[ELFSH_SECTION_ALTPLT],
                                diff, off);
            diff = (eresi_Addr) altgot->shdr->sh_addr - got->shdr->sh_addr +
                   got->shdr->sh_size;
            elfsh_encodeplt(file, extplt, diff, off);
        }
    }

    /* Activate ALTGOT */
    if (elfsh_redirect_pltgot(file, altgot, got, plt, enew) < 0)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "PLTGOT redirection failed", -1);

    /* Activate EXTPLT */
    if (elfsh_extplt_mirror_sections(file) < 0)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "Section mirroring failed", -1);

#if	__DEBUG_COPYPLT__
    printf("[DEBUG_COPYPLT] Section Mirrored Successfully ! \n");
#endif


    /* Everything is 0k4y */
    if (elfsh_sync_sorted_symtab(symtab) < 0)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "symtab synchronisation failed", -1);
    if (elfsh_sync_sorted_symtab(dynsym) < 0)
        PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
                     "dynsym synchronisation failed", -1);
    elfsh_sync_sectnames(file);
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
示例#14
0
/**
 * Change endianess of .dynamic 
 * @param newent
 * @return
 */
int		elfsh_endianize_dynamic(elfshsect_t *newent)
{	  
  elfsh_Dyn	*dyn;
  u_int		idx;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* Sanity check */
  if (!newent)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		      "Invalid NULL parameter", -1);

#if __BYTE_ORDER == __LITTLE_ENDIAN
  if (newent->parent->hdr->e_ident[EI_DATA] == ELFDATA2MSB) {
#elif __BYTE_ORDER == __BIG_ENDIAN
  if (newent->parent->hdr->e_ident[EI_DATA] == ELFDATA2LSB) {
#else
#error Unexpected __BYTE_ORDER !
#endif
    dyn = (elfsh_Dyn *) elfsh_readmem(newent);
    for (idx = 0; idx < newent->shdr->sh_size / sizeof(elfsh_Dyn); idx++)
      {
	dyn[idx].d_tag      = swaplong(dyn[idx].d_tag);
	dyn[idx].d_un.d_val = swaplong(dyn[idx].d_un.d_val);
      }
  }
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}



/**
 * Return a ptr on the dynamic section 
 * @param file
 * @param num
 * @return
 */
elfsh_Dyn	*elfsh_get_dynamic(elfshobj_t *file, u_int *num)
{
  elfshsect_t	*newent = NULL; /* to shut gcc up with -Wall */
  int		nbr;
  elfsh_Dyn	*ret;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  if (file->secthash[ELFSH_SECTION_DYNAMIC] == NULL)
    {
      newent = elfsh_get_section_by_type(file, SHT_DYNAMIC, NULL, NULL, &nbr, 0);
      if (newent == NULL)
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			  "Unable to get .dynamic by type", NULL);
      file->secthash[ELFSH_SECTION_DYNAMIC] = newent;
    }    
  
  newent = file->secthash[ELFSH_SECTION_DYNAMIC];
  nbr = file->secthash[ELFSH_SECTION_DYNAMIC]->shdr->sh_size / 
    sizeof(elfsh_Dyn);
  if (num != NULL)
    *num = nbr;

  if (newent->data == NULL)
    {
      newent->data = elfsh_load_section(file, newent->shdr);
      if (newent->data == NULL)
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			  "Unable to load .dynamic", NULL);
      elfsh_endianize_dynamic(newent);
    }

  ret = (elfsh_Dyn *) elfsh_readmem(newent);
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, ret);
}
示例#15
0
/*
 * returns 0 on success, non-zero if not all textures were properly extracted.
 */
int decompile(listitem_t *wadlist, char *section, void *texture, void *pnames)
{
	int	rc = 0;
	int	i, j;
	int	patches_found;
	int	*p1;
	char	*p2;
	short	*p3;
	int	num_tex;
	int	off_tex;
	short	dummy;
	short	width, height, num_pat;
	short	xoff, yoff, pnum;
	char	tname[9];
	FILE	*fp = NULL;
	char	fn[50];

	/* initialize */
	memset(&tname[0], 0, sizeof tname);

	/* get number of textures in texture lump */
	p1 = (int *) texture;
	num_tex = *p1;
	swaplong(&num_tex);
	printf("  found %d textures\n", num_tex);

	/* loop over all textures */
	for (i = 0; i < num_tex; i++) {
 
		/* offset for texture in lump */
		p1 = (int *) texture + i + 1;
		off_tex = *p1;
		swaplong(&off_tex);
		p2 = (char *) texture + off_tex;

		/* get name of texture */
		strncpy(&tname[0], p2, 8);
		{
		  int n;
		  for (n = 0; n < sizeof tname; n++)
			  tname[n] = toupper(((unsigned char *) tname)[n]);
		}
		if (wildcard != NULL && fnmatch(wildcard, tname, 0) != 0)
			continue;

		/* get texture composition */
		p3 = (short *) (p2 + 8);
		dummy = *p3++;		/* always 0 */
		dummy = *p3++;		/* always 0 */
		width = *p3++;
		swapint(&width);
		height = *p3++;
		swapint(&height);
		dummy = *p3++;		/* always 0 */
		dummy = *p3++;		/* always 0 */
		num_pat = *p3++;
		swapint(&num_pat);

		printf("  decompiling texture %s, %d patches, %dx%d\n",
		  &tname[0], num_pat, width, height);

		/* grow the texture buffer if necessary */
		{
		  unsigned long newsize = width * height;
		  if ((size_t) newsize != newsize) {
		    err("Texture too big, size_t overflow (%hd x %hd). Skipping.",
			width, height);
		    rc = 1;
		    continue;
		  }
		  if (newsize > img_buf_sz) {
		    unsigned char *newbuf = realloc(img_buf, newsize);
		    if (newbuf == NULL) {
		      err("Texture too big, not enough memory (%d x %d). Skipping.",
			  width, height);
		      rc = 1;
		      continue;
		    }
		    img_buf_sz = newsize;
		    img_buf    = newbuf;
		  }
		}

		/* want text file too? */
		if (tflag) {
		  strcpy(&fn[0], "textures/");
		  if (preserve_case)
		    strcat(&fn[0], &tname[0]);
		  else
		    strlcat(&fn[0], &tname[0]);
		  strcat(&fn[0], ".wgc");
		  if ((fp = fopen(&fn[0], "w")) == NULL) {
		    err("can't open %s for writing", &fn[0]);
		    exit(1);
		  }
		  fprintf(fp, "%s_START\n", section);
		  fprintf(fp, "  %s %d %d %d\n", &tname[0], width, height,
		      num_pat);
		}

		/* clear pixel buffer */
		memset(img_buf, 255, img_buf_sz);

		/* loop over all patches for the texture */
		patches_found = 0;
		for (j = 0; j < num_pat; j++) {
		  const char *patchname = NULL;
		  listitem_t *wad;

		  xoff = *p3++;
		  swapint(&xoff);
		  yoff = *p3++;
		  swapint(&yoff);
		  if (yoff < 0)
                    yoff = 0;
		  pnum = *p3++;
		  swapint(&pnum);
		  dummy = *p3++;	/* always 1, stepdir? what is that?? */
		  dummy = *p3++;	/* always 0 for colormap 0 */
		  for (wad = wadlist; wad != NULL; wad = wad->next) {
		    if (get_patch(wad->wf, fp, pnames, width, height,
			  xoff, yoff, pnum, &patchname) == 0) {
		      patches_found++;
		      break;
		    }
		  }
		  if (wad == NULL)
		    printf("    Warning: patch \"%.8s\" is missing\n",
			patchname);
		}

		if (patches_found == 0 && mpatch_policy != OIT_ALWAYS) {
		  printf("    Warning: skipping void texture \"%s\".\n", tname);
		  rc = 1;
		}
		else if (patches_found < num_pat && mpatch_policy == OIT_IF_ALL) {
		  printf("    Warning: skipping incomplete texture \"%s\".\n", tname);
		  rc = 1;
		}
		else
		  if (extract)
		    write_ppm(&tname[0], width, height);

		/* terminate and close the text file too */
		if (tflag) {
		  fprintf(fp, "%s_END\n", section);
		  if (fclose(fp)) {
		    err("%s: %s", fn, strerror(errno));
		    exit(1);
		  }
		}
	}
	return rc;
}
示例#16
0
int get_patch(wadfile_t *wf, FILE *fp, void *pnames, short width, short height,
	       short xoff, short yoff, short pnum, const char **patchname)
{
	int		i;
	int		x, y;
	int		n;
	int		*p1;
	char		*p2;
	int		p_num;
	char		name[9];
	unsigned char	*picture;
	short		pwidth;
	int		*columns;
	unsigned char	*post;

	/* initialization */
	memset(&name[0], 0, 9);

	/* number of patches in PNAMES */
	p1 = (int *) pnames;
	p_num = *p1++;
	swaplong(&p_num);
	if (pnum > p_num) {
	  err("texture uses patch %d, but PNAMES has %d patches only", pnum, p_num);
	  exit(1);
	}

	/* lookup name for that patch */
	p2 = ((char *) p1) + 8 * pnum;
	*patchname = (const char *) p2;
	strncpy(&name[0], p2, 8);
	for (i = 0; i < 8; i++) {
		name[i] = toupper(name[i]);
	}

	/* and get that picture lump */
	if ((picture=(unsigned char *)get_lump_by_name(wf, &name[0])) == NULL) {
		return 1;
	}

	/* copy picture data into pixel buffer */
	pwidth = *((short *) picture);
	swapint(&pwidth);
	printf("    Got patch %s, width %d, x=%d y=%d\n", &name[0], pwidth,
			xoff, yoff);
	columns = (int *) (picture + 8);
	for (x = 0; x < pwidth; x++) {
	  swaplong(columns);
	  post = picture + *columns++;
	  y = (int) *post++;
	  while (y != 255) {
	    n = (int) *post++;
	    post++;	/* first byte unused */
	    for (i = 0; i < n; i++) {
		if ((y+yoff+i >= 0) && (x+xoff >= 0) &&
		    (y+yoff+i < height) && (x+xoff < width))
		  img_buf[(y+yoff+i) * width + (x+xoff)] = *post;
		post++;
	    }
	    post++;	/* last byte unused */
	    y = (int) *post++;
	  }
	}

	/* text file too? */
	if (tflag) {
	  fprintf(fp, "    %s %d %d\n", &name[0], xoff, yoff);
	}

	/* free picture lump memory */
	free(picture);
	return 0;
}