コード例 #1
0
ファイル: resext.cpp プロジェクト: killbug2004/IDAplugins
//---------------------------------------------------------------------------
static void store(const void *Data, uint32 size)
{
    static rhdr_end_t   re;
    static rhdr_name_t  zname = { { 0xFFFF } };
    static const uint32 zero4 = 0;

    rhdr_beg_t rh;
    size_t len = sizeof(rh) + sizeof(re);

    if ( Names[0].len != 0 )
        len += Names[0].len;
    else
        len += sizeof(zname);

    if ( Names[1].len != 0 )
        len += Names[1].len;
    else
        len += sizeof(zname);

    rh.HeaderSize = (uint32)len;
    rh.DataSize   = size;
    re.LanguageId = Names[2].Id;
    qfwrite(fr, &rh, sizeof(rh));

    if ( Names[0].len != 0 )
    {
        qfwrite(fr, Names[0].name, Names[0].len);
    }
    else
    {
        zname.Id = Names[0].Id;
        qfwrite(fr, &zname, sizeof(zname));
    }

    if ( Names[1].len != 0 )
    {
        qfwrite(fr, Names[1].name, Names[1].len);
    }
    else
    {
        zname.Id = Names[1].Id;
        qfwrite(fr, &zname, sizeof(zname));
    }

    qfwrite(fr, &re, sizeof(re));
    if ( Data )  // for 'primary' header
    {
        qfwrite(fr, Data, size);
        len += size;
    }
    if ( len & 3 )
        qfwrite(fr, &zero4, 4 - (len & 3));
}
コード例 #2
0
uint8_t ADMFile::flush(void)
{
 ADM_assert(_fill<=ADM_FILE_BUFFER);
        if(_fill)
        {
                
                qfwrite(_buffer,_fill,1,_out);
                
                _curPos+=_fill;
#ifdef ADMF_DEBUG                
                printf("Flushing %lu bytes, now at :%lu\n",_fill,_curPos);
#endif                
                _fill=0;
        }
        return 1;
}
コード例 #3
0
ファイル: py_fpro.hpp プロジェクト: AmesianX/src
 //--------------------------------------------------------------------------
 int write(PyObject *py_buf)
 {
   PYW_GIL_CHECK_LOCKED_SCOPE();
   if ( !PyString_Check(py_buf) )
     return 0;
   // Just so that there is no risk that the buffer returned by
   // 'PyString_AS_STRING' gets deallocated within the
   // Py_BEGIN|END_ALLOW_THREADS section.
   borref_t py_buf_ref(py_buf);
   void *p = (void *)PyString_AS_STRING(py_buf);
   Py_ssize_t sz = PyString_GET_SIZE(py_buf);
   int rc;
   Py_BEGIN_ALLOW_THREADS;
   rc = qfwrite(fp, p, sz);
   Py_END_ALLOW_THREADS;
   return rc;
 }
コード例 #4
0
ファイル: map.cpp プロジェクト: nealey/vera
//----------------------------------------------------------------------
int32 print_loader_messages(char str[MAXSTR], const char *cmt)
{
  ssize_t i, j, len;
  netnode temp(curClass.msgNode);

  i = 0;
  if((j = (size_t)temp.altval(i)) == 0) {
badbase:
    DESTROYED("loader_message");
  } else do {
    if((len = temp.supstr(i, str, MAXSTR)) <= 0) goto badbase;
    if(cmt) {
      if(printf_line(0, "%s%s", cmt, str)) return(-1);
    } else {
      qfwrite(myFile, str, len);
      if(qfputc('\n', myFile) == EOF) return(-1);
    }
  }while(++i < j);
  return((int32)i);
}
コード例 #5
0
ファイル: unlib.cpp プロジェクト: trietptm/usefulres
//--------------------------------------------------------------------------
int main(int argc,char *argv[]) {
  int i;
  fprintf(stderr,"ARM Library unpacker. Copyright 1997 by Ilfak Guilfanov. Version 1.00\n");
  if ( argc < 2 ) fatal("Usage: unlib libfile");
  strcpy(infile,argv[1]);
  FILE *fp = qfopen(infile,"rb");
  if ( fp == NULL ) fatal("Can't open library %s",infile);
  chunk_header_t hd;
  if ( qfread(fp, &hd, sizeof(hd)) != sizeof(hd)
        || (hd.ChunkFileId != AOF_MAGIC && hd.ChunkFileId != AOF_MAGIC_B) )
    fatal("Bad library format");
  if ( hd.ChunkFileId == AOF_MAGIC_B ) {            // BIG ENDIAN
    mf = 1;
    hd.max_chunks = swap(hd.max_chunks);
    hd.num_chunks = swap(hd.num_chunks);
  }

  chunk_entry_t *ce = qnewarray(chunk_entry_t,size_t(hd.max_chunks));
  if ( ce == NULL ) nomem("chunk entries (%d)",size_t(hd.max_chunks));
  qfread(fp, ce, sizeof(chunk_entry_t)*size_t(hd.max_chunks));
  if ( mf ) for ( i=0; i < hd.max_chunks; i++ ) swap_chunk_entry(ce+i);

  int vrsn = -1;
  int diry = -1;
  int data = 0;
  for ( i=0; i < hd.max_chunks; i++ ) {
    if ( ce[i].file_offset == 0 ) continue;
    if ( strncmp(ce[i].chunkId,LIB_DIRY,sizeof(ce[i].chunkId)) == 0 ) diry = i;
    if ( strncmp(ce[i].chunkId,LIB_VRSN,sizeof(ce[i].chunkId)) == 0 ) vrsn = i;
    if ( strncmp(ce[i].chunkId,LIB_DATA,sizeof(ce[i].chunkId)) == 0 ) data++;
  }
  if ( diry == -1 ) fatal("Can't find library directory!");
  if ( data == 0  ) fatal("No modules in the library!");
  if ( vrsn == -1 ) fatal("Can't determine library version!");
  ulong *version = (ulong *)read_chunk(fp,ce,vrsn);
  if ( mf ) *version = swap(*version);
  if ( *version != 1 ) fatal("Wrong library version (%ld)",*version);
  qfree(version);

  ulong *dir = (ulong *)read_chunk(fp,ce,diry);
  ulong *end = dir + size_t(ce[diry].size/4);
  while ( dir < end ) {
    ulong idx  = *dir++;
    /* ulong elen = */ *dir++;
    ulong dlen = *dir++;
    if ( mf ) {
      idx = swap(idx);
      dlen = swap(dlen);
    }
    if ( idx != 0 ) {
      printf("%ld. %s\n",idx,dir);
      strncpy(modname,(char *)dir,sizeof(modname));
      modname[sizeof(modname)-1] = '\0';
      void *core = read_chunk(fp,ce,idx);
      outfp = qfopen(modname,"wb");
      if ( outfp == NULL ) {
        warning("Can't open output file %s",modname);
      } else {
        qfwrite(outfp,core,size_t(ce[size_t(idx)].size));
        qfclose(outfp);
      }
      qfree(core);
    }
    dir += size_t(dlen/4);
  }
  qfree(dir);

  qfclose(fp);
  return 0;
}
コード例 #6
0
//****************************************************************
uint8_t
mpegWritter::dopass2 (const char *name, char *statname, uint32_t final_size, uint32_t bitrate, ADM_MPEGTYPE mpegtype, int matrix, uint8_t interlaced, uint8_t bff,	// WLA
		      uint8_t widescreen)
{
  int intra, q;
  uint32_t size;
  AVDMGenericVideoStream *incoming;

  FILE *fd = NULL;
  uint64_t total_size = 0;
  uint32_t len, flags, type, outquant, audiolen;
  uint32_t sample_target = 0;
  double sample_time;
  ADMBitstream bitstream;

  memset (quantstat, 0, 32);

  incoming = getLastVideoFilter (frameStart, frameEnd - frameStart);
  if (!_audio)
    {
      if (!(fd = qfopen (name, "wb")))
	return 0;
    }

//      if(!init(name,mpegtype,interlaced,widescreen))
  if (!init (name, mpegtype, interlaced, bff, widescreen))	// WLA
    {
      printf ("Mpeg2 init failed\n");
      return 0;
    }
  printf ("\n mpeg2enc init done \n");

  ADM_assert (aImage);
  ADM_assert (_buffer_out);
  encoding->reset ();
  encoding->setFrame (0, _total);

/*-------------------- Pass 1 over, go to pass 2 --------------------------------*/

  ADM_assert (_ratecontrol->startPass2 (final_size, _total));

  encoding->setPhasis ("2nd Pass");
  q = 2;

  //mpegvbr.maxAllowedBitrate=(bitrate*1000)>>3;//(bitrate*1000)>>3;
  //mpegvbr.maxAllowedBitrate=(9000*1000)>>3; // enable stuff in xvid


//->
  switch (mpegtype)
    {
    case ADM_SVCD:

      Mpeg2encSVCD * dec;
      dec = new Mpeg2encSVCD (_w, _h);
      dec->setMatrix (matrix);
//                              dec->init(q,bitrate,_fps1000,interlaced,widescreen);
      dec->init (q, bitrate, _fps1000, interlaced, bff, widescreen, 0);	// WLA
      _codec = dec;
      encoding->setCodec ("SVCD");
      printf ("Svcd  max bitrate : %d\n", bitrate);
      break;
    case ADM_DVD:
      {

	Mpeg2encDVD *dec;
	dec = new Mpeg2encDVD (_w, _h);
	dec->setMatrix (matrix);
//                      dec->init(q,bitrate,_fps1000,interlaced,widescreen);
	dec->init (q, bitrate, _fps1000, interlaced, bff, widescreen, 0);	// WLA
	_codec = dec;
	printf ("DVD  max bitrate : %d\n", bitrate);
	encoding->setCodec ("DVD");
      }
      break;
    default:
      ADM_assert (0);
      break;
    }
  encoding->setPhasis ("2nd Pass");
  if (_muxer)
    {
      encoding->
	setAudioCodec (getStrFromAudioCodec (_audio->getInfo ()->encoding));
      sample_time = _total;
      sample_time *= 1000;
      sample_time /= _fps1000;	// target_time in second
      sample_time *= _audio->getInfo ()->frequency;
      sample_target = (uint32_t) floor (sample_time);
    }
  bitstream.data = _buffer_out;
  for (uint32_t i = 0; i < _total; i++)
    {
      if (!incoming->getFrameNumberNoAlloc (i, &size, aImage, &flags))
	{
          GUI_Error_HIG (_("Encoding error"), NULL);
	  if (!_audio)
	    qfclose (fd);
	  end ();
	  return 0;
	}
      encoding->setFrame (i, _total);

      if (i < MPEG_PREFILL)
	{

	  _codec->encode (aImage, &bitstream);	//_buffer_out , &len,&flags,&outquant);   
	  quantstat[bitstream.out_quantizer]++;
	  continue;
	}
     	// Set
      //
      ADM_rframe ftype, ztype;
      uint32_t qz;
      ADM_assert (_ratecontrol->getQz (&qz, &ztype));
      q = qz;
      //_codec->setQuantize(q);
      bitstream.in_quantizer = q;
      _codec->encode (aImage, &bitstream);	//_buffer_out , &len,&flags,&outquant);
      quantstat[bitstream.out_quantizer]++;
      encoding->setQuant (bitstream.out_quantizer);

      switch (bitstream.flags)
	{
	case AVI_KEY_FRAME:
	  ftype = RF_I;
	  break;
	case AVI_B_FRAME:
	  ftype = RF_B;
	  break;
	default:
	  ftype = RF_P;
	  break;
	}
      if (ftype != ztype)
	{
	  printf ("**Frame type does not match %d %d\n", ztype, ftype);
	}
      //aprintf("inquant  : %02d outquant %02d Intra %d size :%d flags %x\n",
      //              q,outquant,intra,len,flags);
      ADM_assert (_ratecontrol->
		  logPass2 (bitstream.out_quantizer, ftype, bitstream.len));
      total_size += bitstream.len;
      encoding->feedFrame (bitstream.len);
      if (!_muxer)
	{
	  qfwrite (_buffer_out, bitstream.len, 1, fd);
	  fflush (fd);
	}
      else
	{

	  // write video
	  _muxer->writeVideoPacket (&bitstream);

	  PACK_AUDIO;
	}



      if (!encoding->isAlive ())
	{
	  print_quant_stat (name);
	  end ();
	  qfclose (fd);
	  return 0;
	}
    }

//--
// flush queue
  for (uint32_t i = 0; i < MPEG_PREFILL; i++)
    {

      ADM_rframe ftype;
      uint32_t qz;
      ADM_assert (_ratecontrol->getQz (&qz, &ftype));
      q = qz;
      //_codec->setQuantize(q);
      bitstream.in_quantizer = q;
      _codec->encode (aImage, &bitstream);	//_buffer_out , &len,&flags,&outquant);
      quantstat[bitstream.out_quantizer]++;
      encoding->setQuant (bitstream.out_quantizer);
      switch (bitstream.flags)
	{
	case AVI_KEY_FRAME:
	  ftype = RF_I;
	  break;
	case AVI_B_FRAME:
	  ftype = RF_B;
	  break;
	default:
	  ftype = RF_P;
	  break;
	}
      //aprintf("inquant  : %02d outquant %02d Intra %d size :%d flags %x\n",
      //                      q,outquant,intra,len,flags);
      ADM_assert (_ratecontrol->
		  logPass2 (bitstream.out_quantizer, ftype, bitstream.len));

      total_size += bitstream.len;
      if (!_muxer)
	{
	  qfwrite (_buffer_out, bitstream.len, 1, fd);
	  fflush (fd);
	}
      else
	{
	  // write video
            _muxer->writeVideoPacket (&bitstream);
	  PACK_AUDIO;

	}

      //      printf("\n pipe opened %ld\n",i);
      encoding->feedFrame (bitstream.len);	// Set
      encoding->setQuant (bitstream.out_quantizer);
      encoding->setFrame (i, MPEG_PREFILL);

    }
//--                    
  if (!_muxer)
    qfclose (fd);
  else
    {
      _muxer->close ();
      delete _muxer;
      _muxer = NULL;
    }

  print_quant_stat (name);
  end ();
  return 1;
}
コード例 #7
0
/*
	Save as with the external mpeg2enc

*/
uint8_t
mpegWritter::save_regular (const char *name, ADM_MPEGTYPE mpegtype, int qz, int bitrate, int matrix, uint8_t interlaced, uint8_t bff,	// WLA
			   uint8_t widescreen)
{
  uint32_t size;
  AVDMGenericVideoStream *incoming;

  FILE *fd = NULL;
  uint64_t total_size = 0;
  uint32_t len, flags;
  uint32_t outquant;
  uint32_t audiolen = 0;
  DIA_encoding *encoding;
  uint32_t sample_target = 0;
  double sample_time;
  ADMBitstream bitstream;
  incoming = getLastVideoFilter (frameStart, frameEnd - frameStart);
  _total = incoming->getInfo ()->nb_frames;
  _fps1000 = incoming->getInfo ()->fps1000;
  if (!_total)
    {
      GUI_Error_HIG (_("No frames to encode"),
                     _("Please check markers. Is \"A>\" == \">B\"?"));
      return 0;
    }

  printf ("Br:%d, qz:%d\n", bitrate, qz);
  if (!_audio)
    {
      if (!(fd = qfopen (name, "wb")))
	return 0;
    }
  else
    {
      ADM_assert (_muxer);
      sample_time = _total;
      sample_time *= 1000;
      sample_time /= _fps1000;	// target_time in second
      sample_time *= _audio->getInfo ()->frequency;
      sample_target = (uint32_t) floor (sample_time);

    }


  _w = incoming->getInfo ()->width;
  _h = incoming->getInfo ()->height;


  _page = _w * _h;
  _page += _page >> 1;

//                      if(!init(name,ADM_VCD,interlaced,widescreen)) return 0;
  if (!init (name, ADM_VCD, interlaced, bff, widescreen))
    return 0;			//WLA
  printf ("\n mpeg2enc init done \n");


  //_buffer       =new uint8_t[_w*_h*2];
  aImage = new ADMImage (_w, _h);
  _buffer_out = new uint8_t[_w * _h * 2];

  ADM_assert (aImage);
  ADM_assert (_buffer_out);

  encoding = new DIA_encoding (_fps1000);

  encoding->setPhasis ("Encoding.");
  encoding->setFrame (0, _total);
//      printf("Br:%d, qz:%d\n",bitrate,qz);

  switch (mpegtype)
    {
    case ADM_VCD:
      {
	encoding->setCodec ("VCD.");
	Mpeg2encVCD *dec;
	dec = new Mpeg2encVCD (_w, _h);
//                                      dec->init(1,0,_fps1000,interlaced,widescreen);
	dec->init (1, 0, _fps1000, interlaced, bff, widescreen, 0);	// WLA
	_codec = dec;
      }
      break;
    case ADM_SVCD:

      Mpeg2encSVCD * dec;
      dec = new Mpeg2encSVCD (_w, _h);
      dec->setMatrix (matrix);
//                                      dec->init(qz,bitrate,_fps1000,interlaced,widescreen);
      dec->init (qz, bitrate, _fps1000, interlaced, bff, widescreen, 0);
      // WLA
      _codec = dec;
      encoding->setCodec ("SVCD.");

      break;

    case ADM_DVD:
      {
	Mpeg2encDVD *dec;
	dec = new Mpeg2encDVD (_w, _h);
	dec->setMatrix (matrix);
//                                      dec->init(qz,bitrate,_fps1000,interlaced,widescreen);
	dec->init (qz, bitrate, _fps1000, interlaced, bff, widescreen, 0);
	// WLA
	_codec = dec;
	encoding->setCodec ("DVD.");

      }
      break;
    default:
      ADM_assert (0);
    }

  printf ("\n--encoding started--\n");
  if (_muxer)
    {
      if (audioProcessMode ())
	encoding->
	  setAudioCodec (getStrFromAudioCodec (_audio->getInfo ()->encoding));
      else
	encoding->setAudioCodec ("Copy");
      switch (_outputAs)
	{

	case MUXER_TS:
	  encoding->setContainer ("Mpeg TS");
	  break;
	case MUXER_VCD:
	  encoding->setContainer ("Mpeg VCD");
	  break;
	case MUXER_SVCD:
	  encoding->setContainer ("Mpeg SVCD");
	  break;
	case MUXER_DVD:
	  encoding->setContainer ("Mpeg DVD");
	  break;
	default:
	  ADM_assert (0);
	}

    }
  else
    encoding->setContainer ("Mpeg ES");
  bitstream.data = _buffer_out;
  for (uint32_t i = 0; i < _total; i++)
    {
      if (!incoming->getFrameNumberNoAlloc (i, &size, aImage, &flags))
	{
	  delete encoding;
          GUI_Error_HIG (_("Encoding error"), NULL);
	  if (fd)
	    qfclose (fd);
	  end ();
	  return 0;
	}
      bitstream.cleanup (i);
      bitstream.in_quantizer=0;
      _codec->encode (aImage, &bitstream);
      //_buffer_out , &len,&flags,&outquant);
      total_size += bitstream.len;
      encoding->feedFrame (bitstream.len);
      encoding->setQuant (bitstream.out_quantizer);
      encoding->setFrame (i, _total);
      // Null frame are only possible
      // when in prefill state for mpeg-X
      if (!len)
	continue;
      if (_muxer)
	{
#warning FIXME
#warning FIXME
#warning FIXME
#warning FIXME
	  _muxer->writeVideoPacket (&bitstream);
	  PACK_AUDIO;

	}
      else
	{
            qfwrite (_buffer_out, bitstream.len, 1, fd);
	  fflush (fd);
	}

      aprintf (" outquant %02d  size :%d flags %x\n", outquant, len, flags);

      if (!encoding->isAlive ())
	{
	  delete encoding;
	  end ();
	  if (fd)
	    qfclose (fd);
	  return 0;
	}
    }
  encoding->setPhasis ("Finishing");
  bitstream.data = _buffer_out;
  for (uint32_t i = 0; i < MPEG_PREFILL; i++)
    {
      bitstream.cleanup (i);
      _codec->encode (aImage, &bitstream);	//_buffer_out , &len,&flags);
      total_size += bitstream.len;
      encoding->feedFrame (bitstream.len);
      if (!_muxer)
          qfwrite (_buffer_out, bitstream.len, 1, fd);
      else
	{
            _muxer->writeVideoPacket (&bitstream);
	  PACK_AUDIO;
	}

      //      printf("\n pipe opened %ld\n",i);
      encoding->setFrame (i, _total);

    }
  delete encoding;

  if (!_muxer)
    qfclose (fd);
  else
    {
      _muxer->close ();
      delete _muxer;
      _muxer = NULL;
      deleteAudioFilter (_audio);
      _audio = NULL;
    }
  end ();
  return 1;

}
コード例 #8
0
ファイル: extractors.cpp プロジェクト: idkwim/ExtractMachO
/*
 * function to extract fat archives
 */
uint8_t 
extract_fat(ea_t address, char *outputFilename)
{
#if DEBUG
    msg("[DEBUG] Trying to extract a fat binary target!\n");
#endif
    struct fat_header fatHeader;
    if(!get_many_bytes(address, &fatHeader, sizeof(struct fat_header)))
    {
        msg("[ERROR] Read bytes failed!\n");
        return 1;
    }
    if(validate_fat(fatHeader, address))
        return 1;
    // for fat binaries things are much easier to dump
    // since the fat_arch struct contains total size of the binary :-)
    // open output file
    FILE *outputFile = qfopen(outputFilename, "wb+");
    if (outputFile == NULL)
    {
        msg("[ERROR] Could not open %s file!\n", outputFilename);
        return 1;
    }
    // write fat_header
    qfwrite(outputFile, &fatHeader, sizeof(struct fat_header));
    // read fat_arch
    ea_t fatArchAddress = address + sizeof(struct fat_header);
    uint32_t fatArchSize = sizeof(struct fat_arch)*ntohl(fatHeader.nfat_arch);
    // write all fat_arch structs
    void *fatArchBuf = qalloc(fatArchSize);
    if(!get_many_bytes(fatArchAddress, fatArchBuf, fatArchSize))
    {
        msg("[ERROR] Read bytes failed!\n");
        return 1;
    }
    qfwrite(outputFile, fatArchBuf, fatArchSize);
    qfree(fatArchBuf);
    // write the mach-o binaries inside the fat archive
    for (uint32_t i = 0; i < ntohl(fatHeader.nfat_arch) ; i++)
    {
        struct fat_arch tempFatArch;
        // read the fat_arch struct
        if(!get_many_bytes(fatArchAddress, &tempFatArch, sizeof(struct fat_arch)))
        {
            msg("[ERROR] Read bytes failed!\n");
            return 1;
        }
        // read and write the mach-o binary pointed by each fat_arch struct
        void *tempBuf = qalloc(ntohl(tempFatArch.size));
        if(!get_many_bytes(address+ntohl(tempFatArch.offset), tempBuf, ntohl(tempFatArch.size)))
        {
            msg("[ERROR] Read bytes failed!\n");
            return 1;
        }
        qfseek(outputFile, ntohl(tempFatArch.offset), SEEK_SET);
        qfwrite(outputFile, tempBuf, ntohl(tempFatArch.size));
        qfree(tempBuf);
        // advance to next fat_arch struct
        fatArchAddress += sizeof(struct fat_arch);
    }
    // all done
    qfclose(outputFile);
    return 0;
}
コード例 #9
0
ファイル: extractors.cpp プロジェクト: idkwim/ExtractMachO
uint8_t
extract_mhobject(ea_t address, char *outputFilename)
{
    uint32 magicValue = get_long(address);
    
    struct mach_header *mach_header = NULL;
    struct mach_header_64 *mach_header64 = NULL;
    
    uint8_t arch = 0;
    if (magicValue == MH_MAGIC)
    {
#if DEBUG
        msg("[DEBUG] Target is 32bits!\n");
#endif
        mach_header = (struct mach_header *)qalloc(sizeof(struct mach_header));
        // retrieve mach_header contents
        if(!get_many_bytes(address, mach_header, sizeof(struct mach_header)))
        {
            msg("[ERROR] Read bytes failed!\n");
            return 1;
        }
    }
    else if (magicValue == MH_MAGIC_64)
    {
#if DEBUG
        msg("[DEBUG] Target is 64bits!\n");
#endif
        mach_header64 = (struct mach_header_64 *)qalloc(sizeof(struct mach_header_64));
        if(!get_many_bytes(address, mach_header64, sizeof(struct mach_header_64)))
        {
            msg("[ERROR] Read bytes failed!\n");
            return 1;
        }
        arch = 1;
    }
    
    // open output file
    FILE *outputFile = qfopen(outputFilename, "wb+");
    if (outputFile == NULL)
    {
        msg("[ERROR] Could not open %s file!\n", outputFilename);
        return 1;
    }
    
    /*
     * we need to write 3 distinct blocks of data:
     * 1) the mach_header
     * 2) the load commands
     * 3) the code and data from the LC_SEGMENT/LC_SEGMENT_64 commands
     */
    
    // write the mach_header to the file
    if (arch)
        qfwrite(outputFile, mach_header64, sizeof(struct mach_header_64));
    else
        qfwrite(outputFile, mach_header, sizeof(struct mach_header));
    
    // swap the endianness of some fields if it's powerpc target
    if (magicValue == MH_CIGAM)
    {
        mach_header->ncmds = ntohl(mach_header->ncmds);
        mach_header->sizeofcmds = ntohl(mach_header->sizeofcmds);
    }
    else if (magicValue == MH_CIGAM_64)
    {
        mach_header64->ncmds = ntohl(mach_header64->ncmds);
        mach_header64->sizeofcmds = ntohl(mach_header64->sizeofcmds);
    }

    // read the load commands
    uint32_t ncmds = arch ? mach_header64->ncmds : mach_header->ncmds;
    uint32_t sizeofcmds = arch ? mach_header64->sizeofcmds : mach_header->sizeofcmds;
    uint32_t headerSize = arch ? sizeof(struct mach_header_64) : sizeof(struct mach_header);
    
    uint8_t *loadcmdsBuffer = NULL;
    loadcmdsBuffer = (uint8_t*)qalloc(sizeofcmds);
    
    get_many_bytes(address + headerSize, loadcmdsBuffer, sizeofcmds);
    // write all the load commands block to the output file
    // only LC_SEGMENT commands contain further data
    qfwrite(outputFile, loadcmdsBuffer, sizeofcmds);
    
    // and now process the load commands so we can retrieve code and data
    struct load_command loadCommand;
    ea_t cmdsBaseAddress = address + headerSize;    
    
    // read segments so we can write the code and data
    // only the segment commands have useful information
    for (uint32_t i = 0; i < ncmds; i++)
    {
        get_many_bytes(cmdsBaseAddress, &loadCommand, sizeof(struct load_command));
        struct segment_command segmentCommand;
        struct segment_command_64 segmentCommand64;
        // swap the endianness of some fields if it's powerpc target
        if (magicValue == MH_CIGAM || magicValue == MH_CIGAM_64)
        {
            loadCommand.cmd = ntohl(loadCommand.cmd);
            loadCommand.cmdsize = ntohl(loadCommand.cmdsize);
        }

        // 32bits targets
        if (loadCommand.cmd == LC_SEGMENT)
        {
            get_many_bytes(cmdsBaseAddress, &segmentCommand, sizeof(struct segment_command));
            // swap the endianness of some fields if it's powerpc target
            if (magicValue == MH_CIGAM)
            {
                segmentCommand.nsects   = ntohl(segmentCommand.nsects);
                segmentCommand.fileoff  = ntohl(segmentCommand.fileoff);
                segmentCommand.filesize = ntohl(segmentCommand.filesize);
            }

            ea_t sectionAddress = cmdsBaseAddress + sizeof(struct segment_command);
            struct section sectionCommand; 
            // iterate thru all sections to find the first code offset
            // FIXME: we need to find the lowest one since the section info can be reordered
            for (uint32_t x = 0; x < segmentCommand.nsects; x++)
            {
                get_many_bytes(sectionAddress, &sectionCommand, sizeof(struct section));
                // swap the endianness of some fields if it's powerpc target
                if (magicValue == MH_CIGAM)
                {
                    sectionCommand.offset = ntohl(sectionCommand.offset);
                    sectionCommand.nreloc = ntohl(sectionCommand.nreloc);
                    sectionCommand.reloff = ntohl(sectionCommand.reloff);
                }
                if (sectionCommand.nreloc > 0)
                {
                    uint32_t size = sectionCommand.nreloc*sizeof(struct relocation_info);
                    uint8_t *relocBuf = (uint8_t*)qalloc(size);
                    get_many_bytes(address + sectionCommand.reloff, relocBuf, size);
                    qfseek(outputFile, sectionCommand.reloff, SEEK_SET);
                    qfwrite(outputFile, relocBuf, size);
                    qfree(relocBuf);
                }
                sectionAddress += sizeof(struct section);
            }
            // read and write the data
            uint8_t *buf = (uint8_t*)qalloc(segmentCommand.filesize);
            get_many_bytes(address + segmentCommand.fileoff, buf, segmentCommand.filesize);
            // always set the offset
            qfseek(outputFile, segmentCommand.fileoff, SEEK_SET);
            qfwrite(outputFile, buf, segmentCommand.filesize);
            qfree(buf);
        }
        // we need this to dump missing relocations
        else if (loadCommand.cmd == LC_SYMTAB)
        {
            struct symtab_command symtabCommand;
            get_many_bytes(cmdsBaseAddress, &symtabCommand, sizeof(struct symtab_command));
            // swap the endianness of some fields if it's powerpc target
            if (magicValue == MH_CIGAM || magicValue == MH_CIGAM_64)
            {
                symtabCommand.nsyms   = ntohl(symtabCommand.nsyms);
                symtabCommand.symoff  = ntohl(symtabCommand.symoff);
                symtabCommand.stroff  = ntohl(symtabCommand.stroff);
                symtabCommand.strsize = ntohl(symtabCommand.strsize);
            }
            
            if (symtabCommand.symoff > 0)
            {
                void *buf = qalloc(symtabCommand.nsyms*sizeof(struct nlist));
                get_many_bytes(address + symtabCommand.symoff, buf, symtabCommand.nsyms*sizeof(struct nlist));
                qfseek(outputFile, symtabCommand.symoff, SEEK_SET);
                qfwrite(outputFile, buf, symtabCommand.nsyms*sizeof(struct nlist));
                qfree(buf);
            }
            if (symtabCommand.stroff > 0)
            {
                void *buf = qalloc(symtabCommand.strsize);
                get_many_bytes(address + symtabCommand.stroff, buf, symtabCommand.strsize);
                qfseek(outputFile, symtabCommand.stroff, SEEK_SET);
                qfwrite(outputFile, buf, symtabCommand.strsize);
                qfree(buf);
            }
        }
        // 64bits targets
        // FIXME: will this work ? needs to be tested :-)
        else if (loadCommand.cmd == LC_SEGMENT_64)
        {
            get_many_bytes(cmdsBaseAddress, &segmentCommand64, sizeof(struct segment_command_64));
            // swap the endianness of some fields if it's powerpc target
            if (magicValue == MH_CIGAM_64)
            {
                segmentCommand64.nsects   = ntohl(segmentCommand64.nsects);
                segmentCommand64.fileoff  = bswap64(segmentCommand64.fileoff);
                segmentCommand64.filesize = bswap64(segmentCommand64.filesize);
            }

            ea_t sectionAddress = cmdsBaseAddress + sizeof(struct segment_command_64);
            struct section_64 sectionCommand64;
            for (uint32_t x = 0; x < segmentCommand64.nsects; x++)
            {
                get_many_bytes(sectionAddress, &sectionCommand64, sizeof(struct section_64));
                // swap the endianness of some fields if it's powerpc target
                if (magicValue == MH_CIGAM_64)
                {
                    sectionCommand64.offset = ntohl(sectionCommand64.offset);
                    sectionCommand64.nreloc = ntohl(sectionCommand64.nreloc);
                    sectionCommand64.reloff = ntohl(sectionCommand64.reloff);
                }
                
                if (sectionCommand64.nreloc > 0)
                {
                    uint32_t size = sectionCommand64.nreloc*sizeof(struct relocation_info);
                    uint8_t *relocBuf = (uint8_t*)qalloc(size);
                    get_many_bytes(address + sectionCommand64.reloff, relocBuf, size);
                    qfseek(outputFile, sectionCommand64.reloff, SEEK_SET);
                    qfwrite(outputFile, relocBuf, size);
                    qfree(relocBuf);
                }
                sectionAddress += sizeof(struct section_64);
            }
            // read and write the data
            uint8_t *buf = (uint8_t*)qalloc(segmentCommand64.filesize);
            get_many_bytes(address + segmentCommand64.fileoff, buf, segmentCommand64.filesize);
            qfseek(outputFile, segmentCommand64.fileoff, SEEK_SET);
            qfwrite(outputFile, buf, segmentCommand64.filesize);
            qfree(buf);
        }
        cmdsBaseAddress += loadCommand.cmdsize;
    }
    
    // all done, close file and free remaining buffers!
    qfclose(outputFile);
    qfree(mach_header);
    qfree(mach_header64);
    qfree(loadcmdsBuffer);
    return 0;
    
}
コード例 #10
0
ファイル: extractors.cpp プロジェクト: idkwim/ExtractMachO
/*
 * function to extract non-fat binaries, 32 and 64bits
 */
uint8_t 
extract_macho(ea_t address, char *outputFilename)
{
    uint32 magicValue = get_long(address);
    
    struct mach_header *mach_header = NULL;
    struct mach_header_64 *mach_header64 = NULL;
    
    uint8_t arch = 0;
    if (magicValue == MH_MAGIC || magicValue == MH_CIGAM)
    {
#if DEBUG
        msg("[DEBUG] Target is 32bits!\n");
#endif
        mach_header = (struct mach_header *)qalloc(sizeof(struct mach_header));
        // retrieve mach_header contents
        if(!get_many_bytes(address, mach_header, sizeof(struct mach_header)))
        {
            msg("[ERROR] Read bytes failed!\n");
            return 1;
        }
    }
    else if (magicValue == MH_MAGIC_64 || magicValue == MH_CIGAM_64)
    {
#if DEBUG
        msg("[DEBUG] Target is 64bits!\n");
#endif
        mach_header64 = (struct mach_header_64 *)qalloc(sizeof(struct mach_header_64));
        if(!get_many_bytes(address, mach_header64, sizeof(struct mach_header_64)))
        {
            msg("[ERROR] Read bytes failed!\n");
            return 1;
        }
        arch = 1;
    }
    else
    {
        msg("[ERROR] Unknown target!\n");
        return 1;
    }
    
    // open output file
    FILE *outputFile = qfopen(outputFilename, "wb+");
    if (outputFile == NULL)
    {
        msg("[ERROR] Could not open %s file!\n", outputFilename);
        return 1;
    }
    
    /*
     * we need to write 3 distinct blocks of data:
     * 1) the mach_header
     * 2) the load commands
     * 3) the code and data from the LC_SEGMENT/LC_SEGMENT_64 commands
     */
    
    // write the mach_header to the file
    if (arch)
        qfwrite(outputFile, mach_header64, sizeof(struct mach_header_64));
    else
        qfwrite(outputFile, mach_header, sizeof(struct mach_header));
    
    // swap the endianness of some fields if it's powerpc target
    if (magicValue == MH_CIGAM)
    {
        mach_header->ncmds = ntohl(mach_header->ncmds);
        mach_header->sizeofcmds = ntohl(mach_header->sizeofcmds);
    }
    else if (magicValue == MH_CIGAM_64)
    {
        mach_header64->ncmds = ntohl(mach_header64->ncmds);
        mach_header64->sizeofcmds = ntohl(mach_header64->sizeofcmds);
    }
    
    // read the load commands
    uint32_t ncmds      = arch ? mach_header64->ncmds : mach_header->ncmds;
    uint32_t sizeofcmds = arch ? mach_header64->sizeofcmds : mach_header->sizeofcmds;
    uint32_t headerSize = arch ? sizeof(struct mach_header_64) : sizeof(struct mach_header);
    
    uint8_t *loadcmdsBuffer = NULL;
    loadcmdsBuffer = (uint8_t*)qalloc(sizeofcmds);
    
    get_many_bytes(address + headerSize, loadcmdsBuffer, sizeofcmds);
    // write all the load commands block to the output file
    // only LC_SEGMENT commands contain further data
    qfwrite(outputFile, loadcmdsBuffer, sizeofcmds);
    
    // and now process the load commands so we can retrieve code and data
    struct load_command loadCommand;
    ea_t cmdsBaseAddress = address + headerSize;    
    ea_t codeOffset = 0;
    
    // read segments so we can write the code and data
    // only the segment commands have useful information
    for (uint32_t i = 0; i < ncmds; i++)
    {
        get_many_bytes(cmdsBaseAddress, &loadCommand, sizeof(struct load_command));
        struct segment_command segmentCommand;
        struct segment_command_64 segmentCommand64;
        // swap the endianness of some fields if it's powerpc target
        if (magicValue == MH_CIGAM || magicValue == MH_CIGAM_64)
        {
            loadCommand.cmd     = ntohl(loadCommand.cmd);
            loadCommand.cmdsize = ntohl(loadCommand.cmdsize);
        }
        
        // 32bits targets
        // FIXME: do we also need to dump the relocs info here ?
        if (loadCommand.cmd == LC_SEGMENT)
        {
            get_many_bytes(cmdsBaseAddress, &segmentCommand, sizeof(struct segment_command));
            // swap the endianness of some fields if it's powerpc target
            if (magicValue == MH_CIGAM)
            {
                segmentCommand.nsects   = ntohl(segmentCommand.nsects);
                segmentCommand.fileoff  = ntohl(segmentCommand.fileoff);
                segmentCommand.filesize = ntohl(segmentCommand.filesize);
            }
            // the file offset info in LC_SEGMENT is zero at __TEXT so we need to get it from the sections
            // the size is ok to be used
            if (strncmp(segmentCommand.segname, "__TEXT", 16) == 0)
            {
                ea_t sectionAddress = cmdsBaseAddress + sizeof(struct segment_command);
                struct section sectionCommand; 
                // iterate thru all sections to find the first code offset
                // FIXME: we need to find the lowest one since the section info can be reordered
                for (uint32_t x = 0; x < segmentCommand.nsects; x++)
                {
                    get_many_bytes(sectionAddress, &sectionCommand, sizeof(struct section));
                    // swap the endianness of some fields if it's powerpc target
                    if (magicValue == MH_CIGAM)
                        sectionCommand.offset = ntohl(sectionCommand.offset);
                    
                    if (strncmp(sectionCommand.sectname, "__text", 16) == 0)
                    {
                        codeOffset = sectionCommand.offset;
                        break;
                    }
                    sectionAddress += sizeof(struct section);
                }
            }
            // for all other segments the fileoffset info in the LC_SEGMENT is valid so we can use it
            else
            {
                codeOffset = segmentCommand.fileoff;
            }
            // read and write the data
            uint8_t *buf = (uint8_t*)qalloc(segmentCommand.filesize);
            get_many_bytes(address + codeOffset, buf, segmentCommand.filesize);
            // always set the offset
            qfseek(outputFile, codeOffset, SEEK_SET);
            qfwrite(outputFile, buf, segmentCommand.filesize);
            qfree(buf);
        }
        // 64bits targets
        else if (loadCommand.cmd == LC_SEGMENT_64)
        {
            get_many_bytes(cmdsBaseAddress, &segmentCommand64, sizeof(struct segment_command_64));
            // swap the endianness of some fields if it's powerpc target
            if (magicValue == MH_CIGAM_64)
            {
                segmentCommand64.nsects   = ntohl(segmentCommand64.nsects);
                segmentCommand64.fileoff  = bswap64(segmentCommand64.fileoff);
                segmentCommand64.filesize = bswap64(segmentCommand64.filesize);
            }

            if(strncmp(segmentCommand64.segname, "__TEXT", 16) == 0)
            {
                ea_t sectionAddress = cmdsBaseAddress + sizeof(struct segment_command_64);
                struct section_64 sectionCommand64;
                for (uint32_t x = 0; x < segmentCommand64.nsects; x++)
                {
                    get_many_bytes(sectionAddress, &sectionCommand64, sizeof(struct section_64));
                    // swap the endianness of some fields if it's powerpc target
                    if (magicValue == MH_CIGAM_64)
                        sectionCommand64.offset = ntohl(sectionCommand64.offset);

                    if (strncmp(sectionCommand64.sectname, "__text", 16) == 0)
                    {
                        codeOffset = sectionCommand64.offset;
                        break;
                    }
                    sectionAddress += sizeof(struct section_64);
                }
            }
            else
            {
                codeOffset = segmentCommand64.fileoff;
            }
            // read and write the data
            uint8_t *buf = (uint8_t*)qalloc(segmentCommand64.filesize);
            get_many_bytes(address + codeOffset, buf, segmentCommand64.filesize);
            qfseek(outputFile, codeOffset, SEEK_SET);
            qfwrite(outputFile, buf, segmentCommand64.filesize);
            qfree(buf);
        }
        cmdsBaseAddress += loadCommand.cmdsize;
    }
    
    // all done, close file and free remaining buffers!
    qfclose(outputFile);
    qfree(mach_header);
    qfree(mach_header64);
    qfree(loadcmdsBuffer);
    return 0;
}