KAPITALSIN > TUTORIA
PNGFIXER, la utilidad para modificar ficheros png de los archivos VIS3
(1/1)
Fl0ppy:
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: ---/*-
*|:_____: _____ __________ ._________ |
*||__ |/ /.\______ \./ _______/ |
*| / __/ ___/ . | ²__/ /\_____ \ |
*| / \ \_ . | \_____/ \ \_| /|
*| \ \ \_ . | : . : \_______/ |
*| \___\____\ .:____| : |
*| 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;
}
--- Fin del código ---
Más en el adjunto
Navegación
Ir a la versión completa