向JPG文件中追加内容的测试

今天做个测试,就是如何用图片文件传递自己的一些隐藏信息。

首先明白,所有的文件都有头信息,所以不能在头文件中开始追加,因为是测试,我选择了在文件的最后追加。。。

选择非位图文件JPEG文件为测试目标。

思路很简单,定义一个常量byte[]。
读取目标文件,获得目标文件的byte[],然后把文件内容重新写入一个新的文件,在最后把常量byte[]追加上去。

读取新建立的文件,读取最后制定长度的byte[],就是我们要的byte[].

以下例子仅是一个测试程序。

package com.zhanglihai.test;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
 *<P>Title:</P>
 *<P>Description:</P>
 *<P>Copyright:Copyright(c)2004</P>
 *<P>Company:</P>
 *@author:zhanglihai
 *@version:1.0
 *@date:2004-12-22
 */
public class SuperAddBinaryInfo{
    /**
     *
     */
    private static byte[] addBytes=new String("abc123").getBytes();
    private static StringsourceFile="D:/work_test/icon.jpg";
    private static StringaddFile="D:/work_test/icona.jpg";
    public SuperAddBinaryInfo(){
    }
    /**
     *读取目标文件
     *@throwsException
     */
    public static void writeAdd()throwsException{
        FileInputStream input=new FileInputStream(sourceFile);
        ByteArrayOutputStream out=new ByteArrayOutputStream(52);
       int b=-1;
       while((b=input.read())!=-1){
           out.write(b);
       }
       /**
        *生成目标文件
        */
        FileOutputStream output= newFileOutputStream(addFile);
        output.write(out.toByteArray());
       /**
        *此处追加信息
        */
        output.write(addBytes);
        output.flush();
        output.close();
    }
    /**
     *从追加后的文件中读取原来字符串。
     *@throwsException
     */
    public static void readAdd() throws Exception{
        FileInputStream input= new FileInputStream(addFile);
        ByteArrayOutputStream out= new ByteArrayOutputStream(52);
       int b=-1;
       while((b=input.read())!=-1){
           out.write(b);
       }
        out.flush();
        out.close();
        /******追加后文件的长度*****/
      byte[] bytes=out.toByteArray();
        /********获得原始文件的长度,也就是追加字符的起始点*******/
       int len=(bytes.length-addBytes.length);
        /*******创建一个byte用来还原*************/
      byte[] bs=new byte[addBytes.length];
       for(int i=len;i<bytes.length;i++){
           bs[i-len]=bytes[i];
       }
        System.out.println(newString(bs));
    }
    public static void main(String[]args) throws Exception{
        writeAdd();
        readAdd();
    }
}

利用以上的实现,我们可以在jpeg文件中传递一些数据,当然可以设置图片最后的某一个byte开始到某一个byte结束。
追加后的图片仍然可以正常显示,JPEG,GIF格式点文件,在文件后端多几个byte是不影响显示的。但是对于BMP等位图文件是不可以的。

PS:这是JPEG格式天生的缺陷所致,黑客利用这个缺陷制造各种病毒。有时候我们看到的是一张图片,你可以将它的扩展名修改一下,就得到了另一个文件。
利用copy+ 也可以实现类似的功能。

这张图是一个鸭子,如果将其修改成一个EXE文件,执行该文件就能得到一个神奇的程序。

分享到: 更多