<-- Flare-On 2015 Index / pngsteggo.cpp 
1
pngsteggo.cpp

#include <png.h> #include <stdio.h> #include <stdlib.h> typedef unsigned char byte; // // flare2015crackme8_pngSteggoExtract() // int flare2015crackme8_pngSteggoExtract(int argc, char** argv) { int iRetCode = 0; //check args const char* pszOutFile = "decoded.bin"; if (argc<=1) { printf("syntax: %s <PNG_file>\n",argv[0]); printf("outputs to %s\n",pszOutFile); iRetCode = 2; } else { FILE* pFileInput = NULL; const char* pszInputFile = argv[1]; unsigned char arHeader[8]; //open input file pFileInput = fopen(pszInputFile,"rb"); if(!pFileInput) { printf("ERROR: unable to open: %s\n",pszInputFile); } else { //read PNG signature to ensure we're dealing with a PNG fread(arHeader,1,sizeof(arHeader),pFileInput); if (png_sig_cmp(arHeader,0,sizeof(arHeader))) { printf("ERROR: %s is not a PNG file!\n",pszInputFile); } else { //init png_struct for reading PNG file png_struct* pPng = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL); if (!pPng) { printf("ERROR: bad PNG file (error #1)\n"); } else { //init png_info structure png_info* pPngInfo = png_create_info_struct(pPng); png_info* pPngInfoEnd = png_create_info_struct(pPng); if (!pPngInfo || !pPngInfoEnd) { printf("ERROR: PNG info initialization failed (0x%08p, 0x%08p)\n",pPngInfo,pPngInfoEnd); } else { //init the default io to stdC streams png_init_io(pPng,pFileInput); //notify libPng that we already read signature header from file stream png_set_sig_bytes(pPng,sizeof(arHeader)); //read entire PNG file into memory, performing no translations on the data png_read_png(pPng,pPngInfo,PNG_TRANSFORM_IDENTITY,NULL); //retrieve rows of image data in an array of pointers to the pixel data for each row. byte** pImageRows = png_get_rows(pPng,pPngInfo); //close file fclose(pFileInput); pFileInput = NULL; // // Decode least significant bit // //ensure we're dealing with 8-bit depth if (8 != pPng->bit_depth) { printf("ERROR: PNG bit depth must be 8 bits, but it is %u bits\n",pPng->bit_depth); } else if (!pPng->width || !pPng->height) { printf("ERROR: must contain at least a 1 x 1 pixel (width=%u, height=%u)\n",pPng->width,pPng->height); } else { //open the output file FILE* pFileOutput = fopen(pszOutFile,"wb"); if(!pFileOutput) { printf("unable to open: %s\n",pszOutFile); } else { printf("processing %u x %u image...\n",pPng->width,pPng->height); byte chCurByte = 0; unsigned int uIdxCurBit = 0; unsigned int uBytesWrote = 0; //loop through each row byte** ppRow = pImageRows; byte** ppRowEnd = pImageRows+pPng->height; while (ppRow < ppRowEnd) { //loop through each column byte (multiples of 3 bytes per pixel are each RGB components, // a distinction we don't care about because we treat all bytes equally byte* pCol = *ppRow; byte* pColEnd = pCol + (pPng->width*3); while (pCol < pColEnd) { //accumulate next least significant bit from current byte as our next-most data bit chCurByte |= (*pCol & 1) << uIdxCurBit++; if (8 == uIdxCurBit) { //write it to file fputc(chCurByte,pFileOutput); chCurByte = 0; uIdxCurBit = 0; ++uBytesWrote; } ++pCol; } //while each byte ++ppRow; } //while each row //write any left-over bits if (uIdxCurBit) { fputc(chCurByte,pFileOutput); ++uBytesWrote; } //close output file fclose(pFileOutput); pFileOutput = NULL; printf("successfully extracted %u bytes to %s (from %u pixels)\n",uBytesWrote,pszOutFile,pPng->width*pPng->height); } //output file opened successfully } //bit depth OK } //png_create_info_struct() //cleanup read struct png_destroy_read_struct(&pPng,&pPngInfo,&pPngInfoEnd); } //png_create_read_struct() succeeded } //input file is png } //input file opened successfully } //args OK return(iRetCode); } //flare2015crackme8_pngSteggoExtract() // // main() - program entry point // int main(int argc, char** argv) { return(flare2015crackme8_pngSteggoExtract(argc,argv)); } //main()

 1:1