隐写技巧——利用PNG文件格式隐藏Payload(三)

关注 2017-01-03 15:13:25 查看数 5256 ,评论数 0 专题
 部分代码见《隐写技巧——利用PNG文件格式隐藏Payload(二)》

05  去除多余数据

上面提到,去除辅助数据块的内容对PNG图像的浏览没有影响,下面就尝试去除PNG文件的所有辅助数据块

1、工具实现

如图,使用Hex Editor去除辅助数据块gAMA、cHRM和bKGD 647 如图,文件大小变化,但不影响PNG文件浏览 648

2、程序实现

去除所有辅助数据块,只提取关键信息。程序先对ChunkName作判断,忽略非关键数据块(Ancillary Chunk)的内容,并保存为new.png 保存为compress.cpp,完整代码为:
#include<stdio.h>
#include<string.h>


unsigned int GetCrc32(unsignedchar*InStr,unsigned int len){       

           unsignedint Crc32Table[256];     

           unsignedint i,j;       
           unsignedint Crc;       

           for(i = 0; i < 256; i++){       

                       Crc= i;       

                       for (j = 0;j < 8; j++){       

                                   if(Crc & 1)       

                                               Crc= (Crc >> 1) ^ 0xEDB88320;       

                                   else      

                                               Crc>>= 1;     

                       }       

                       Crc32Table[i]= Crc;       

           }       




           Crc=0xffffffff;       

           for(unsignedint m=0; m<len; m++){         

                       Crc= (Crc >> 8) ^ Crc32Table[(Crc & 0xFF) ^InStr[m]];       

           }    




           Crc^= 0xFFFFFFFF;    

           returnCrc;       

}       




int main(int argc, char* argv[])

{

           FILE*fp,*fpnew;  

           unsignedchar *buf=NULL;

           unsignedint len=0;

           unsignedint ChunkLen=0;

           unsignedint ChunkCRC32=0;

           unsignedint ChunkOffset=0;        

           unsignedint crc32=0;

           unsignedint i=0,j=0;

           unsignedcharSignature[8]={0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a};         

           unsignedchar IEND[12]={0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82};       




           if((fp=fopen("c:\\test\\0.png","rb+"))==NULL)

                       return0; 

           if((fpnew=fopen("c:\\test\\new.png","wb"))==NULL)

                       return0; 

           fseek(fp,0,SEEK_END);

           len=ftell(fp);

           buf=newunsigned char[len];

           fseek(fp,0,SEEK_SET);

           fread(buf,len,1,fp);

           printf("TotalLen=%d\n",len);

           printf("----------------------------------------------------\n");

           fseek(fp,8,SEEK_SET);

           ChunkOffset=8;

           i=0;

           fwrite(Signature,8,1,fpnew);

           while(1)

           {

                       i++;

                       j=0;

                       memset(buf,0,len);

                       fread(buf,4,1,fp);

                      fwrite(buf,4,1,fpnew);

                       ChunkLen=(buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|buf[3];

                       fread(buf,4+ChunkLen,1,fp);

                       printf("[+]ChunkName:%c%c%c%c                ",buf[0],buf[1],buf[2],buf[3]);

                       if(strncmp((char*)buf,"IHDR",4)==0|strncmp((char*)buf,"PLTE",4)==0|strncmp((char*)buf,"IDAT",4)==0)

                       {          

                                   printf("PaletteChunk\n");




                                   fwrite(buf,4+ChunkLen,1,fpnew);

                       }

                       else

                       {

                                   printf("AncillaryChunk\n");

                                   fseek(fpnew,-4,SEEK_CUR);

                                   j=1;

                       }

                       printf("  ChunkOffset:0x%08x       \n",ChunkOffset);

                       printf("   ChunkLen:%10d             \n",ChunkLen);

                       crc32=GetCrc32(buf,ChunkLen+4);

                       printf("   ExpectCRC32:%08X\n",crc32);

                       fread(buf,4,1,fp);

                       ChunkCRC32=(buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|buf[3];

                       printf("   ChunkCRC32:%08X                    ",ChunkCRC32);

                       if(crc32!=ChunkCRC32)

                                   printf("[!]CRC32CheckError!\n");

                       else

                       {

                                   printf("CheckSuccess!\n\n");

                                   if(j==0)

                                               fwrite(buf,4,1,fpnew);

                       }

                       ChunkLen=ftell(fp);

                       if(ChunkLen==(len-12))

                       {

                                   printf("\n----------------------------------------------------\n");

                                   printf("TotalChunk:%d\n",i);                       

                                   break;

                       }

           }

           fwrite(IEND,12,1,fpnew);

           fclose(fp);

           fclose(fpnew);

           return0;        

}
如图,左边为原始PNG文件大小,右边为去掉所有辅助数据块后的文件,仍然可以正常浏览 649

06 写入Payload

实例:按照辅助数据块的格式写入Payload 写入的Payload为:calc.exe 辅助数据块设置为:tEXt 对应的完整数据块结构如下: Length:   0000 00 08 Chunk Type Code: 74 45 58 74 Chunk Data:63 61 6c 632e 65 78 65 CRC:fa c4 08 76 写入的十六进制数据如下: 00 00 00 08 74 45 58 74 63 61 6c 63 2e 6578 65 fa c4 08 76 注: 本实例仅作演示,实际使用可换成其他数据块,更加隐蔽

1、工具实现

使用Hex Editor插入数据,如图 650 保存后,不影响PNG文件浏览

2、程序实现

去掉PNG文件所有的辅助数据块后,写入payload数据块tEXt 保存为addpayload.cpp,完整代码:
#include<stdio.h>

#include<string.h>

unsigned int GetCrc32(unsigned char*InStr,unsigned int len){       

            unsignedint Crc32Table[256];     

            unsignedint i,j;       

            unsignedint Crc;       

            for(i = 0; i < 256; i++){       

                        Crc= i;       

                        for(j = 0; j < 8; j++){       

                                    if(Crc & 1)       

                                                Crc= (Crc >> 1) ^ 0xEDB88320;       

                                    else      

                                                Crc>>= 1;     

                        }       

                        Crc32Table[i]= Crc;       

            }       


            Crc=0xffffffff;       

            for(unsignedint m=0; m<len; m++){         

                        Crc= (Crc >> 8) ^ Crc32Table[(Crc & 0xFF) ^ InStr[m]];       

            }
未完待续。。。。。

*来源:RoarTalk 作者:3gstudent Mottoin整理发布

交流评论(0)
Loading...
点击 ,就能发表评论哦~如果您还没有账号,请 一个吧
css.php
正在加载中...