Autor Tema: PNGFIXER, la utilidad para modificar ficheros png de los archivos VIS3  (Leído 63 veces)

Fl0ppy

  • Administrador
  • Usuario Héroe
  • *****
  • Mensajes: 9630
Dije que iria liberando utilidades creadas por KPS y asi se irá haciendo  :ok:

Véase Deponia por ejemplo.

Hace unos 3 años vimos que los png de esos juegos no se podian modificar, estaban "alterados", mediante un artículo de una web que explicaba como hacerlo en un fichero conccreto se desarrolló un programa para "trabajar" con todos los ficheros y no solo eso sinó que también se hizo otro programa para restaurarlos

El programa en si solo se ha usado y compilado bajo Linux, os ponemos su código fuente íntegro y que cada uno se lo compile como quiera

El código

Spoiler for Hiden:
Código: [Seleccionar]
/*-
 *|:_____: _____ __________  ._________ |
 *||__   |/    /.\______   \./ _______/ |
 *|  / __/ ___/ . | ²__/    /\_____   \ |
 *| /  \   \_  .  |  \_____/ \  \_|    /|
 *| \   \    \_ . |    : . :  \_______/ |
 *|  \___\____\  .:____|   :            |
 *|    K.a.P.i.T.a.L.  S i N ' 2013     |
 *+-------------------------------------|
 *|-KPS-                        -2013-  |
 *|  # KPS PNG FIXER PARA VIS ENGINE 3# |
 *
 * ESTE PROGRAMA LO QUE HACE ES ARREGLAR LOS FICHEROS PNG PARA SU MODIFICACIÓN
 * O VISUALIZACION DEL MOTOR VISIONARIE STUDIO 3
 * 
 * LA LICENCIA DE ESTE CODIGO ES DE DOMINIO PUBLICO RESPETANDO
 * A SUS AUTORES
 * 
 * IDEA BASADA EN EL ARTICULO
 *
 * "A New Beginning" - PNG fixing
 * http://www.nullsecurity.org/article/a_new_beginning-png_fixing
 *
 * OTROS GRUPOS SOLO COPIAN, KPS INNOVA
 *
 */
#include <boost/crc.hpp>  // for boost::crc_32_type
//#include <boost/program_options.hpp>  // for boost::crc_32_type
#include <boost/format.hpp>
#include <boost/foreach.hpp>
#include <cstdio>
#include <iostream>
#include <fstream>
#include <cstring>
#include <string>

typedef unsigned int DWORD;

using namespace std;

DWORD crc32(char *buffer, int buffer_length) {
  boost::crc_32_type result;
  result.process_bytes(buffer, buffer_length );
  return result.checksum();
}

/* 'IHDR':             4 bytes
   Width:              4 bytes
   Height:             4 bytes
   Bit depth:          1 byte
   Color type:         1 byte
   Compression method: 1 byte
   Filter method:      1 byte
   Interlace method:   1 byte
*/

int main(int argc, char *argv[]) {
  // Get command line options
  if(argc < 2) {
    cout << "Missing PNG file!" << endl;
    cout << "Usage: pngfixer file.png" << endl;
    exit(-1);
  }

  // Open file
  ifstream infile(argv[1]);
  char buffer[80];

  // Check file is PNG
  infile.read(buffer, 4);
  if(strncmp(buffer, "\x89PNG", 4) !=0 ) {
    // Incorret magik number
    cout << "File is not PNG type!" << endl;
    exit(-2);   
  }
 
  // Read IHDR chunk
     
  // char IHDR[] = "\x49\x48\x44\x52\x61\x64\x31\x9D\x66\x61\x33\x8F\x08\x06\x00\x00\x00";
  // 0xEB35350F
  // char IHDR[] = "\x49\x48\x44\x52\x65\x37\x32\x32\x62\x36\x31\x35\x08\x06\x00\x00\x00";
  // 0x6d9ab2fb;

  char IHDR[17];
  char CHECKSUM[4];
  infile.seekg(12, ios_base::beg);
  infile.read(IHDR, 17);
  infile.read(CHECKSUM, 4);
  DWORD checksum = (((DWORD)CHECKSUM[0])&0xFF) << (3*8)
    | (((DWORD)CHECKSUM[1])&0xFF) << (2*8)
    | (((DWORD)CHECKSUM[2])&0xFF) << (1*8)
    | (((DWORD)CHECKSUM[3])&0xFF) << (0*8);

  // Save original size from the header
  char original_size[8];
  memcpy(original_size, &IHDR[4], 8);

  // Brute force size check
  unsigned int w, h, i;
  for(w = 0; w < 2000; w++) {
    for(h = 0; h < 2000; h++) {
      *(DWORD*)&IHDR[4] = w;
      __asm__("bswap %0" : "+r" (*(DWORD*)&IHDR[4]));
      *(DWORD*)&IHDR[8] = h;
      __asm__("bswap %0" : "+r" (*(DWORD*)&IHDR[8]));

      // Correct size: W:164 x H:187
      // if(w == 256 && h == 512) {
      //   printf("CRC 0x%x\n", crc32(IHDR, 17));
      //   printf("IHDR "); for(int i=0;i<17;i++) printf(" %02x", IHDR[i]);
      //   printf("\n");
      // }

      //if (crc32(IHDR, 17) == 0xEB35350F) {
      //if (crc32(IHDR, 17) == 0x6d9ab2fb) {
      if (crc32(IHDR, 17) == checksum) {
printf("Correct size: W:%d x H:%d\n", w, h);
//printf("Correct size: W:0x%x x H:0x%x\n", w, h);

// Save original size into filename
std::string fname(argv[1]);
std::string hexa;
for(int i = 0; i < sizeof(original_size); i++) {
  //printf("%02x", original_size[i]);
  hexa.append(boost::str(boost::format("%1$02x") % (int) original_size[i]));
}
fname.append(boost::str(boost::format("_%1%.png") % hexa));

std::cout <<std::endl << fname <<std::endl;

// Inject header with correct size
fstream outfile(argv[1], ios::out|ios::in);
outfile.seekp(12, ios_base::beg);
outfile.write(IHDR, 17);
outfile.close();

// Rename file
rename(argv[1],fname.c_str());

// Exit
return 0;
      }
    }
  }

  cout << "Could not find correct size. Failed!" << endl;
  return -3;

}

Más en el adjunto
« Última modificación: 21 de Mayo de 2016, 07:49:50 pm por Fl0ppy »
Siempre que pasa igual sucede lo mismo