Exemple #1
0
/*
Saves a corrupted rom to the given filename. It will automatically provide
an extension if one is not given.

@param filename - The file to save to.
*/
void PSPCorruption::save(std::string filename)
{
  filename += ".iso";

  if (boost::filesystem::exists(filename) && std::remove(filename.c_str()) != 0)
  {
    throw InvalidFileException("Could not delete already existing file: " + filename);
  }

  if (info->save_file() != "")
  {
    boost::filesystem::copy_file(this->m_temp_file, info->save_file());
  }
  else
  {
    boost::filesystem::copy_file(this->m_temp_file, filename);
  }

  if (boost::filesystem::remove(this->m_temp_file) == false)
  {
    throw InvalidFileException("Could not remove temp file: " + this->m_temp_file);
  }

  this->m_saved = true;
}
Exemple #2
0
PSPCorruption::~PSPCorruption()
{
  if (boost::filesystem::exists(this->m_temp_file))
  {
    if (std::remove(this->m_temp_file.c_str()) != 0)
    {
      throw InvalidFileException("Could not delete temp file: " + this->m_temp_file);
    }
  }
}
H5RandomReader::H5RandomReader(const std::string fileName, const std::string groupPath) throw (InvalidFileException) {

    try {
        file.openFile(fileName, H5F_ACC_RDONLY);}
    catch ( H5::FileIException ) {
        throw InvalidFileException("Cannot acces file");}
    try {
        group = file.openGroup(groupPath);}
    catch ( H5::GroupIException ) {
        file.close();
        throw InvalidFileException("Cannot access group");}
    /*
     * extract timeline. This is also necessary to get the nbSteps.
     */
    try {
        timeline = group.openDataSet("timeline");
    	nSteps = timeline.getSpace().getSimpleExtentNpoints();}
    catch ( H5::DataSetIException error ) {
        //error.printError();
        group.close();
        file.close();
        throw InvalidFileException("Cannot access timeline dataset");}
    if (logging::info)
        std::cerr << "Opened group \"" <<  fileName << groupPath << "\" which has " << nSteps << " steps.\n";
    /*
     * extract objects names in the xpGroup
     */

    std::vector<std::string>  names;
    H5Literate(group.getId(), H5_INDEX_NAME, H5_ITER_INC, NULL, iterInGroup, &names);
    /*
     * extract data from object in xpGroup
     * these data can be of 3 types: matrix, translate or wrench
     * each data are saved in related map
     */
    for (unsigned int i=0; i<names.size(); i++){ //TODO: skip timeline
        H5::DataSet dSet = group.openDataSet(names[i]);
        if (H5Aexists(dSet.getId(), "ArborisViewerType")) {
            H5::Attribute att = dSet.openAttribute("ArborisViewerType");
            std::string type;
            att.read(att.getDataType(), type);
            if (type == "matrix"){
                H5::DataSpace dSpace = dSet.getSpace();
                bool dimension_ok = false;
                if (dSpace.getSimpleExtentNdims()==3) {
                    hsize_t dims[3];
                    dSpace.getSimpleExtentDims (dims);
                    if (dims[0] == nSteps && dims[1] == 4 && dims[2] == 4)
                        dimension_ok = true;}
                if (dimension_ok)
                    matrices[names[i]] = dSet;
                else {
                    if (logging::warning)
                        std::cerr << "Skipping dataset \"" << names[i] << "\" which has wrong dimensions. I was expecting (" << nSteps << ",4,4).\n";
                    dSet.close();}}
            else if (type == "translate"){
                H5::DataSpace dSpace = dSet.getSpace();
                bool dimension_ok = false;
                if (dSpace.getSimpleExtentNdims()==2) {
                    hsize_t dims[2];
                    dSpace.getSimpleExtentDims (dims);
                    if (dims[0] == nSteps && dims[1] == 3)
                        dimension_ok = true;}
                if (dimension_ok)
                    translates[names[i]] = dSet;
                else {
                    if (logging::warning)
                        std::cerr << "Skipping dataset \"" << names[i] << "\" which has wrong dimensions. I was expecting (" << nSteps << ",3).\n";
                    dSet.close();}}
            else if (type == "wrench") {
                H5::DataSpace dSpace = dSet.getSpace();
                bool dimension_ok = false;
                if (dSpace.getSimpleExtentNdims()==2) {
                    hsize_t dims[2];
                    dSpace.getSimpleExtentDims (dims);
                    if (dims[0] == nSteps && dims[1] == 6)
                        dimension_ok = true;}
                if (dimension_ok)
                    wrenches[names[i]] = dSet;
                else {
                    if (logging::warning)
                        std::cerr << "Skipping dataset \"" << names[i] << "\" which as wrong dimensions. I was expecting (" << nSteps << ",6).\n";
                    dSet.close();}}
            else {
                if (logging::warning)
                    std::cerr << "Skipping dataset \"" << names[i] << "\" whose ArborisViewerType attribute as unknown value \"" << type << "\".\n";
                dSet.close();}
            att.close();
        }
        else {
            if (logging::info)
                std::cerr << "Skipping dataset \"" << names[i] << "\" which has no ArborisViewerType attribute.\n";
            dSet.close();
        }
    }
};
Exemple #4
0
/*
Corrupt the loaded file with the parameters in the PSPCorruptionInfo class
*/
void PSPCorruption::corrupt()
{
  if (info->step() > 0 && info->files().size() > 0)
  {
    //  Copy file only if step is valid and there are files to corrupt.
    boost::filesystem::copy_file(this->m_original_file, this->m_temp_file, boost::filesystem::copy_option::overwrite_if_exists);
  }
  else
  {
    std::cout << "Not corrupting: " << info->step() << "\t" << info->files().size() << std::endl;
    return; //  If no step or files to corrupt then return
  }

  //  For counting amount of corruptions
  uint32_t corruptions = 0;

  //  Random number distribution over the byte value range
  std::uniform_int_distribution<int> random(0x00, 0xFF);

  //  Open file for read/write in binary mode
  std::fstream img(this->m_temp_file, std::ios::in | std::ios::out | std::ios::binary);

  //  If image could not be read then throw an exception
  if (!img.good())
  {
    throw InvalidFileException("Could not open temp file: " + this->m_temp_file);
  }

  for (auto& file : info->files())
  {
    if (file == "")
    {
      continue;
    }

    //  Read the file into wad
    Entry entry = (*this->rom)[file];
    //  Get the raw data of the entry
    std::vector<uint8_t> data;

    try
    {
      data = entry.get(img, false);
    }
    catch (...)
    {
      //std::cout << "Could not find file '" << file << "'" << std::endl;
      continue;
    }

    //  If no data, then throw an exception
    if (data.empty())
    {
      //std::cout << "No data found in file '" << file << "'" << std::endl;
      continue;
    }

    for (uint32_t i = info->start(); (i < data.size()) && (i < info->end()); i += info->step())
    {
      if (info->type() == CorruptionType::Shift)
      {
        //  If it's okay to put the other byte in this position then change it
        if (i + info->value() < data.size() && valid_byte(data[i + info->value()], i))
        {
          corruptions++;
          data[i] = data[i + info->value()];
        }
      }
      else if (info->type() == CorruptionType::Swap)
      {

        if (i + info->value() < data.size() &&
          valid_byte(data[i + info->value()], i) &&  //  If it's okay to put the other byte in this position
          valid_byte(data[i], i + info->value()))    //  And it's okay to put this byte in the other position
        {
          corruptions++;
          uint8_t temp = data[i + info->value()];
          data[i] = temp;
          data[i + info->value()] = temp;
        }
      }
      else if (info->type() == CorruptionType::Add)
      {
        //  If the new byte value is valid then do the corruption
        if (valid_byte(data[i] + info->value(), i))
        {
          corruptions++;
          data[i] += info->value();
        }
      }
      else if (info->type() == CorruptionType::Set)
      {
        //  If the set value can be placed here then do it
        if (valid_byte(info->value(), i))
        {
          corruptions++;
          data[i] = info->value();
        }
      }
      else if (info->type() == CorruptionType::Random)
      {
        bool corrupted = false;

        //  Try up to 100 times to corrupt
        for (uint32_t retry = 0; !corrupted && retry < 100; retry++)
        {
          uint8_t rand = random(this->random);
          if (valid_byte(rand, i))
          {
            corruptions++;
            data[i] = rand;
            corrupted = true;
          }
        }
      }
      else if (info->type() == CorruptionType::RotateLeft)
      {
        uint8_t rotate = util::rol<uint8_t>(data[i], info->value());

        if (valid_byte(rotate, i))
        {
          data[i] = rotate;
          corruptions++;
        }
      }
      else if (info->type() == CorruptionType::RotateRight)
      {
        uint8_t rotate = util::ror<uint8_t>(data[i], info->value());

        if (valid_byte(rotate, i))
        {
          data[i] = rotate;
          corruptions++;
        }
      }
      else if (info->type() == CorruptionType::LogicalAnd)
      {
        if (valid_byte(data[i] & info->value(), i))
        {
          data[i] &= info->value();
          corruptions++;
        }
      }
      else if (info->type() == CorruptionType::LogicalOr)
      {
        if (valid_byte(data[i] | info->value(), i))
        {
          data[i] |= info->value();
          corruptions++;
        }
      }
      else if (info->type() == CorruptionType::LogicalXor)
      {
        if (valid_byte(data[i] ^ info->value(), i))
        {
          data[i] ^= info->value();
          corruptions++;
        }
      }
      else if (info->type() == CorruptionType::LogicalComplement)
      {
        if (valid_byte(~data[i], i))
        {
          data[i] = ~data[i];
          corruptions++;
        }
      }
      else
      {
        break;  //  No corruption selected, might as well quit.
      }
    }

    //  Write the modified data back to the file
    entry.write(img, data, false);
  }

  //  Close the file
  img.close();

  //  Tell the user how many bytes were corrupted
  std::cout << corruptions << " bytes corrupted." << std::endl;
}