Codice:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <sstream>
#include <string>
#define COUNTERS_START 19
#define HEADER_END 24
#define CONTENT_ASSET_THUMBNAIL 0x01
#define CONTENT_ASSET_BACKGROUND 0x02
#define CONTENT_ASSET_BANNER 0x04
#define CONTENT_ASSET_BOXART 0x08
#define CONTENT_ASSET_PREVIEW 0x10
#define CONTENT_ASSET_SCREENSHOT 0x20
#define CONTENT_ASSET_NXE_SLOT 0x40
#define CONTENT_ASSET_FULLCOVER 0x80
using namespace std;
char magicBytes[16] = {
0x46, 0x53, 0x44, 0x41, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xAF};
struct assetDetails{
uint8_t type;
uint8_t offset [4];
uint8_t pSize [4];
uint8_t tSize [4];
};
class assetHeader
{
public:
char magic[4];
char version[4];
char assetFlag[4];
int assetCount;
int screenshotCount;
vector <assetDetails> assets;
assetHeader(const char * filename){
char headerBuffer [HEADER_END];
ifstream infile(filename);
if(infile.fail())
{
cout<<"File not found.Aborting"<<endl;
exit(1);
}
infile.read(headerBuffer,HEADER_END);
if(checkMagic(headerBuffer)!=true)
{
cout<<"Header check fail.Aborting"<<endl;
exit(1);
}
cout<<"Header check OK!"<<endl;
memcpy(magic,&headerBuffer[0],4);
memcpy(version,&headerBuffer[4],4);
memcpy(assetFlag,&headerBuffer[12],4);
assetCount=(int)headerBuffer[19];
screenshotCount=(int)headerBuffer[23];
infile.seekg(0x18);
char detailsHeader[20*assetCount];
infile.read(detailsHeader,20*assetCount);
infile.close();
for(uint8_t i=0;i<assetCount;++i)
{
assetDetails tmp;
tmp.type=detailsHeader[3+(i*16)];
memcpy(tmp.offset,&detailsHeader[4+(i*16)],4);
memcpy(tmp.pSize,&detailsHeader[8+(i*16)],4);
memcpy(tmp.tSize,&detailsHeader[12+(i*16)],4);
assets.push_back(tmp);
}
extractDDS(filename);
}
private:
bool checkMagic(const char headerBuffer[HEADER_END]){
char headerSubstr [16];
memcpy(headerSubstr,&headerBuffer[0],16);
return (strcmp(headerBuffer,magicBytes)==0);
}
void extractFile(const uint32_t& DDSOffset,const uint32_t& DDSSize,const char * filename,const uint8_t& counter)
{
stringstream ss;
ss<<"DDS_";
ss<<(int)counter;
ss<<".dds";
string outfileName;
ss>>outfileName;
ifstream infile(filename,ios::binary | ios::in);
ofstream outfile(outfileName.c_str(), ios::binary | ios::out);
infile.seekg(DDSOffset);
uint32_t i=0;
while(i!=DDSSize)
{
outfile.put(infile.get());
i++;
}
outfile.close();
infile.close();
cout<<outfileName<<" extracted. Size:"<<DDSSize<<" KB"<<endl;
}
void extractDDS(const char * filename)
{
for(uint8_t i=0;i<assets.size();++i)
{
assetDetails tmp=assets[i];
stringstream ss_offset,ss_size;
string s_offset,s_size;
uint32_t DDSOffset,DDSSize;
for(uint8_t j=0;j<4;++j)
{
if((int)tmp.tSize[j]<16)
ss_size<<"0";
if((int)tmp.offset[j]<16)
ss_offset<<"0";
ss_offset<<hex<<(int)tmp.offset[j];
ss_size<<hex<<(int)tmp.tSize[j];
}
ss_offset>>s_offset;
ss_size>>s_size;
sscanf(s_offset.c_str(), "%x", &DDSOffset);
sscanf(s_size.c_str(), "%x", &DDSSize);
extractFile(DDSOffset,DDSSize,filename,i);
}
}
};
int main(int argc, char * argv[])
{
cout<<"XTRASSETS 0.1 beta\n";
cout<<"Coded By Ciro\n"<<endl;
if(argc!=2)
{
cout<<"Missing argument!\n";
cout<<"Usage:";
cout<<"XTRASSETS.exe <assets_file>"<<endl;
return 1;
}
assetHeader header(argv[1]);
cout<<"Done!"<<endl;
}
Segnalibri