`
gao_20022002
  • 浏览: 160503 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

关于zip文件的字节码处理

    博客分类:
  • Java
阅读更多

昨天写了一篇关于压缩文件以及压缩文件解压问题,现在对于自己压缩的zip文件,从字节码的角度进行分析。

 

这里主要的知识是对于zip文件压缩格式的了解。

 

第一步:获取文件字节流,这部分代码在以前的程序中大量用到,呵呵,强悍的工具方法,虽然很简单。

final static public byte[] readfile(String name) {
		FileInputStream in = null;
		byte buffer[] = null;
		try {
			in = new FileInputStream(new File(name));
			buffer = new byte[in.available()];
			in.read(buffer);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return buffer;
	}

 现在我们已经获取到了zip压缩文件的字节码数组,下来就是对他的分析了。

在这里,我将文件内容首先简单的分为两个部分,跟格式定义相同:数据区以及目录区。

第二步:读取数据区的数据。

	final static public Map<String, String> parsedata(byte[] b, int pos) {
		Map<String, String> map = new HashMap<String, String>();
		int sig = data(b, pos, 4);
		pos += 4;
		map.put("sig", i2s(sig));
		int zpkware = data(b, pos, 2);
		pos += 2;
		map.put("zpkware", i2s(zpkware));
		int flag = data(b, pos, 2);
		pos += 2;
		map.put("flag", i2s(flag));
		int type = data(b, pos, 2);
		pos += 2;
		map.put("type", i2s(type));
		int time = data(b, pos, 2);
		pos += 2;
		map.put("time", i2s(time));
		int date = data(b, pos, 2);
		pos += 2;
		map.put("date", i2s(date));
		int crc = data(b, pos, 4);
		pos += 4;
		map.put("crc", i2s(crc));
		int zsize = data(b, pos, 4);
		pos += 4;
		map.put("zsize", i2s(zsize));
		int usize = data(b, pos, 4);
		pos += 4;
		map.put("usize", i2s(usize));
		int lname = data(b, pos, 2);
		pos += 2;
		map.put("lname", i2s(lname));
		int laname = data(b, pos, 2);
		pos += 2;
		map.put("laname", i2s(laname));
		byte[] name = new byte[lname];
		for (int i = 0; i < lname; i++) {
			name[i] = b[pos++];
		}
		map.put("name", new String(name));
		map.put("position", i2s(pos));
		map.put("data", "data");
		return map;
	}

 第三步:读取目录区数据。

final static public Map<String, String> parsedir(byte[] b, int pos) {
		Map<String, String> map = new HashMap<String, String>();
		int sig = data(b, pos, 4);
		pos += 4;
		map.put("sig", i2s(sig));
		int zpkware = data(b, pos, 2);
		pos += 2;
		map.put("zpkware", i2s(zpkware));
		int upkware = data(b, pos, 2);
		pos += 2;
		map.put("upkware", i2s(upkware));
		int flag = data(b, pos, 2);
		pos += 2;
		map.put("flag", i2s(flag));
		int type = data(b, pos, 2);
		pos += 2;
		map.put("type", i2s(type));
		int time = data(b, pos, 2);
		pos += 2;
		map.put("time", i2s(time));
		int date = data(b, pos, 2);
		pos += 2;
		map.put("date", i2s(date));
		int crc = data(b, pos, 4);
		pos += 4;
		map.put("crc", i2s(crc));
		int zsize = data(b, pos, 4);
		pos += 4;
		map.put("zsize", i2s(zsize));
		int usize = data(b, pos, 4);
		pos += 4;
		map.put("usize", i2s(usize));
		int lname = data(b, pos, 2);
		pos += 2;
		map.put("lname", i2s(lname));
		int laname = data(b, pos, 2);
		pos += 2;
		map.put("laname", i2s(laname));
		int notes = data(b, pos, 2);
		pos += 2;
		map.put("notes", i2s(notes));
		int disk = data(b, pos, 2);
		pos += 2;
		map.put("disk", i2s(disk));
		int ifile = data(b, pos, 2);
		pos += 2;
		map.put("ifile", i2s(ifile));
		int ofile = data(b, pos, 4);
		pos += 4;
		map.put("ofile", i2s(ofile));
		int phead = data(b, pos, 4);
		pos += 4;
		map.put("phead", i2s(phead));
		byte[] name = new byte[lname];
		for (int i = 0; i < lname; i++) {
			name[i] = b[pos++];
		}
		map.put("name", new String(name));
		map.put("position", i2s(pos));
		map.put("data", "dir");
		return map;
	}

 现在都只是头部信息,对于文件内容没有处理。

第四步:分析整个文件包含的数据区以及目录区数据。

final static public Vector<Map<String, String>> parse(byte[] b) {
		Vector<Map<String, String>> v = new Vector<Map<String, String>>();
		Map<String, String> elem;
		int pos = 0;
		while (pos != -1) {
			elem = parsedata(b, pos);
			v.add(elem);
			pos = new Integer((String) elem.get("position")).intValue();
			pos = searchdata(b, pos);
		}
		pos = searchdir(b, 0);// OK
		while (pos != -1) {
			elem = parsedir(b, pos);
			v.add(elem);
			pos = new Integer((String) elem.get("position")).intValue();
			pos = searchdir(b, pos);
		}
		return v;
	}

第五步:用到的工具方法。

1、将int转换为字符串的。

final static public String i2s(int i) {
		return String.valueOf(i);
	}

 2、寻找数据以及读取字节定位的。

final static public int data(byte[] b, int pos, int times) {
		int record = 0;
		for (int i = 0; i < times; i++) {
			record += b[pos++] << (8 * i);
		}
		return record;
	}

 3、全字节数组寻找数据记录的。

final static public int searchdata(byte[] b, int pos) {
		for (int i = pos; i < b.length; i++) {
			if (i + 4 < b.length) {
				if (data(b, i, 4) == 0x04034B50) {
					return i;
				}
			}
		}
		return -1;
	

 4、全字节数组寻找目录记录的。

final static public int searchdir(byte[] b, int pos) {
		for (int i = pos; i < b.length; i++) {
			if (i + 4 < b.length) {
				if (data(b, i, 4) == 0x02014B50) {
					return i;
				}
			}
		}
		return -1;
	}

 5、验证过程中的输出方法。

	final static public void toString(byte[] b) {
		for (int i = 0; i < b.length; i++) {
			System.out.print(b[i] + " ");
		}
	}

	final static public void toString(Map<String, String> map) {
		Set<String> set = map.keySet();
		for (String string : set) {
			System.out.println(string + ":" + map.get(string));
		}
	}

	final static public void toString(Vector<Map<String, String>> v) {
		Map<String, String> map = null;
		for (int i = 0; i < v.size(); i++) {
			map = v.elementAt(i);
			toString(map);
			System.out.println("--------------------------------------------");
		}
	}

 第六步:测试代码。

	public static void main(String[] args) {
		byte[] b = readfile("D://zipunzip//testzip.zip");
		toString(parse(b));
	}

 

OK,程序完成。

但是还有很大的缺陷,而此种缺陷则是由压缩文件模式引起的。

例如:

缺陷1:分析的压缩文件中对于压缩文件大小以及为压缩文件大小了个字段均为0,顾而无法获取文件内容的具体东西,并且文件内容进行了压缩,难以分析。顾而在程序中自己来检测文件位置来确定,也就出现了多余的position的记录项。

缺陷2:压缩过程由于没有进行属性控制,压缩文件的组织方式是按照文件的存放位置的,没有自己的过滤设置,即按照自己想存放的方式压缩。

 

因此,对于昨天的压缩文件还是要进一步的分析,以压缩成质量高的,可以自己明确分析的压缩文件,而不是压缩仅仅是成功的压缩文件。

 

对于这个问题,关注点集中于ZipEntry类中,没有太多的研究这个类,有谁知道这个里面参数的具体含义,以及如何组织自己的ZipEntry实例,给点指示,谢谢。

 

2
0
分享到:
评论

相关推荐

    rar压缩软件.rar

    RAR 是一个让你在命令行模式中管理压缩文件的控制台应用。RAR 提供压缩、加 密、数据恢复和许多其它此手册中描述的其它功能。 RAR 只支持 RAR 格式压缩文件,它默认有 .rar 扩展名。不支持ZIP 和其他格 式。即使...

    易语言模块大全(共775个模块)

    打开关联文件及调用关于窗口(1.0).zip 打开多文件对话框(1.0).zip 读取超级列表框模块(1.0).zip 多姿网络数据库客户端模块(1.0).zip 动态修改图片组v1.0(1.0).zip 电子琴模块(1.0).zip 电脑安全维护模块(1.0).zip ...

    易语言700模块打包

    打开关联文件及调用关于窗口(1.0).zip 打开多文件对话框(1.0).zip 读取超级列表框模块(1.0).zip 多姿网络数据库客户端模块(1.0).zip 动态修改图片组v1.0(1.0).zip 电子琴模块(1.0).zip 电脑安全维护模块(1.0)....

    安卓APK混淆加固重签名工具1.3.0(解压密码1234).zip

    3.支持DEX代码混淆,可以针对APK字节码进行多种混淆,字符串加密,指令乱序等功能 4.支持资源混淆,可以对APK包内部的资源文件进行混淆处理 5.支持增加包体积,可以随意增加APK包的体积 6.处理后的APK可以有效保护...

    ClassFinal是一款java class文件安全加密工具。.zip

    可避免源码泄漏或字节码被反编译。.zip 软件开发设计:应用软件开发、系统软件开发、移动应用开发、网站开发C++、Java、python、web、C#等语言的项目开发与学习资料 硬件与设备:单片机、EDA、proteus、RTOS、包括...

    RABCDAsm:健壮的ABC(ActionScript字节码)[Dis-]汇编器

    健壮的ABC(ActionScript字节码)[Dis-]汇编器 是实用程序的集合,其中包括ActionScript 3汇编器/反汇编器以及一些用于处理SWF文件的工具。 这些都是: rabcdasm -ABC反汇编程序 rabcasm -ABC汇编程序 abcexport从...

    JAVA上百实例源码以及开源项目

     Java zip压缩包查看程序,应用弹出文件选择框,选择ZIP格式的压缩文件,可以像Winrar软件一样查看压缩文件内部的文件及文件夹,源码截图如上所示。 Java 数字签名、数字证书生成源码 2个目标文件 摘要:JAVA源码,...

    中文简体压缩软件RAR 6.0

    RAR 是一个强力压缩工具,允许你管理和管理压缩文件。控制台 RAR 只支持 RAR 格式,带有的 ".rar" 扩展名的文件。ZIP 和其他格式不被支持。Windows 用户可以 安装图形界面 RAR 版本 - WinRAR,它可以处理更多...

    java开源包1

    提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新加载class文件而无需重启JVM的工具。 PHPJava Bridge php调用java...

    java开源包11

    提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新加载class文件而无需重启JVM的工具。 PHPJava Bridge php调用java...

    java开源包2

    提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新加载class文件而无需重启JVM的工具。 PHPJava Bridge php调用java...

    java开源包3

    提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新加载class文件而无需重启JVM的工具。 PHPJava Bridge php调用java...

    java开源包6

    提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新加载class文件而无需重启JVM的工具。 PHPJava Bridge php调用java...

    java开源包5

    提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新加载class文件而无需重启JVM的工具。 PHPJava Bridge php调用java...

    java开源包10

    提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新加载class文件而无需重启JVM的工具。 PHPJava Bridge php调用java...

    java开源包4

    提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新加载class文件而无需重启JVM的工具。 PHPJava Bridge php调用java...

    java开源包8

    提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新加载class文件而无需重启JVM的工具。 PHPJava Bridge php调用java...

    java开源包7

    提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新加载class文件而无需重启JVM的工具。 PHPJava Bridge php调用java...

    java开源包9

    提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新加载class文件而无需重启JVM的工具。 PHPJava Bridge php调用java...

    java开源包101

    提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新加载class文件而无需重启JVM的工具。 PHPJava Bridge php调用java...

Global site tag (gtag.js) - Google Analytics