`
gao_20022002
  • 浏览: 165571 次
  • 性别: 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
分享到:
评论

相关推荐

    字节码实战包含class,字节码.zip

    它们可以帮助开发者查看类文件的结构,理解字节码指令的含义,甚至修改字节码以实现调试、优化或逆向工程的目的。 5. **字节码优化**: 通过理解字节码,开发者可以进行针对性的优化,比如减少对象创建、优化循环...

    Java 字节码简单说明.zip

    Java字节码是一种低级的、平台无关的指令集,它是Java源代码经过编译器处理后的产物。每条字节码指令通常只占用一个或两个字节,因此得名“字节码”。这种设计使得Java程序能够跨平台运行,因为字节码并不直接对应于...

    修改class字节码需要的工具.zip

    4. **字节码详解与字节码对应16进制网址.txt**: 这个文件可能包含了一些关于Java字节码的详细解释,以及一个链接到资源,该资源提供了字节码指令的16进制表示。理解字节码对于直接编辑字节码文件至关重要,因为字节...

    cglib,字节码生成库是生成和转换Java字节码的高级API。它被aop、测试、数据访问框架用来生成动态代理对象和拦截字段访问。.zip

    字节码是Java平台独立的,由.class文件存储的机器不可理解的指令集。CGlib库利用ASM库(一个底层的Java字节码操作和分析框架)来生成和修改字节码。通过这种方式,开发者可以在程序运行时动态地创建新的类或修改现有...

    JByteMod-1.6.1(java字节码编辑器)简介及下载

    **JByteMod** 是一款专为Java开发者设计的字节码编辑器,它允许用户对JAR文件进行深度操作和修改。在Java编程环境中,字节码是Java虚拟机(JVM)执行的二进制代码,而JByteMod提供了一个用户友好的界面,使得开发者...

    通过Android字节码插桩插件实现Android端无埋点(或自动埋点),并且支持根据配置文件实现业务数据的自动采集。.zip

    字节码插桩是一种动态或静态修改字节码的技术,用于在运行时或编译时插入额外的代码。在Android中,我们可以使用ASM、Dexmaker或ByteBuddy等库来实现字节码插桩。LazierTracker就是基于这些技术,它能够在运行时动态...

    Java字节码加密工具.zip

    在这个名为"Java字节码加密工具.zip"的压缩包中,包含了一个名为"classfinal-master"的项目,这可能是一个开源或商业的Java字节码加密框架的源代码仓库。 字节码加密是通过混淆、加密和解密等技术来改变Java字节码...

    java注解_反射_字节码_类加载机制.zip

    Java字节码是JVM可理解的机器指令集,以`.class`文件的形式存在。当Java源代码被编译后,生成的就是字节码。字节码使得Java具有跨平台性,因为JVM负责将字节码转换为特定硬件平台的机器指令。字节码也可以被反编译,...

    JByteMod-Beta,Java字节码编辑器.zip

    JByteMod-Beta的语法高亮功能使得Java字节码的代码结构更加清晰,更容易识别关键字、变量、方法等元素,帮助开发者快速理解和解析字节码文件。 **2. 实时反编译** 反编译是将已编译的字节码转换回源代码的过程。...

    演示Asm字节码插桩asmd-demo-master.zip

    在本案例"asmd-demo-master.zip"中,我们将探讨Asm库在字节码插桩中的应用。 Asm是一个开源的Java字节码操控和分析框架,它可以用来动态生成类或者分析运行中的Java程序。Asm提供了非常底层的API,可以直接操作字节...

    python字节码详细介绍共2页.pdf.zip

    4. **局部变量和全局变量**:字节码处理函数内部的局部变量和全局变量。 5. **常量池**:包含了函数中使用的常量,如字符串、数字和引用的函数等。 了解Python字节码可以帮助我们进行性能调试和优化,因为我们可以...

    java字节码class文件反编译工具jad_windows版本.zip

    jad_windows版本的安装和使用通常很简单,用户只需要解压下载的zip文件,然后运行其中的jad.exe文件。在命令行界面,用户可以直接输入类文件的路径来反编译,例如: ``` jad -o &lt;class_file&gt;.class ``` 这条命令会将...

    Java虚拟机字节码.zip

    2. **Class文件结构解析**: Java Class文件是Java程序编译后的结果,包含了类的元数据和字节码指令。它的结构包括魔数、版本号、常量池、访问标志、类索引、父类索引、接口索引集合、字段表集合、方法表集合和属性表...

    该项目主要是JAVA字节码的学习项目.zip

    以下是关于Java字节码的详细知识点: 1. **字节码的概念**:Java源代码在编译后生成的是类文件,每个类文件包含字节码,它是二进制形式的指令集,JVM能直接执行。这种设计允许Java程序在任何安装了JVM的平台上运行...

    JAVA字节码编辑工具.zip

    在Java编程语言中,源代码被编译成字节码(.class文件),这是一种平台无关的中间表示形式,可以在Java虚拟机(JVM)上运行。这个工具允许开发者直接对这些字节码进行修改,提供了深入到程序底层操作的可能性,对于...

    基于Java的字节码操作库 BCEL.zip

    Java字节码操作库BCEL(Byte Code Engineering Library)是一个强大的工具,主要用于处理Java类文件。它提供了对字节码的全面访问和控制,允许开发者分析、修改和创建新的Java类。BCEL在许多领域都有应用,如动态...

    基于java的字节码操作库 BCEL.zip

    Java字节码操作库BCEL(Byte Code Engineering Library)是一个强大的工具,主要用于处理Java字节码,它允许开发者分析、创建、修改以及动态生成类。BCEL是Apache软件基金会下的Jakarta项目的一部分,广泛应用于软件...

    vdexExtractor,从vdex文件中反编译和提取android dex字节码的工具.zip

    这时,`vdexExtractor` 工具就显得尤为重要,它是一个开源项目,专门用于从vdex文件中反编译和提取Android的Dex字节码。 **vdexExtractor工作原理** `vdexExtractor` 使用Java编写,它的工作流程包括以下几个步骤...

    Java字节码(.class文件)格式详解((转载)

    Java字节码是Java程序编译后的产物,它以`.class`文件的形式存在,是Java虚拟机(JVM)能够理解和执行的二进制代码。本文将深入解析Java字节码的格式,帮助你理解其背后的运行机制。 1. **Java字节码结构** Java...

Global site tag (gtag.js) - Google Analytics