2011年8月16日星期二

exe4j生成的exe文件的unpack

今天看到一个比较实用的Java软件,想知道它是如何实现的,但是这个软件已经使用exe4j封装成了可执行文件。通过搜索网络,看到下面的这篇文章:

http://www.blogjava.net/cnfree/archive/2010/08/22/329559.html

其中的关键:

  1. exe文件的解码(OR 88)
  2. 使用WinHex从解码后的文件中分离出jar文件

其中第一步在文中已经给出了源代码如下:

import java.io.*;
import java.util.*;
public class gen {
public static void main(String args[]) throws IOException {
        FileInputStream fin = new FileInputStream(args[0]); // 可以将整个exe文件解码
        FileOutputStream fout = new FileOutputStream(args[1]);
        BufferedInputStream bin = new BufferedInputStream(fin);
        BufferedOutputStream bout = new BufferedOutputStream(fout);
int in = 0;
do {
            in = bin.read();
if (in == -1)
break;
            in ^= 0x88;
            bout.write(in);
        } while (true);
        bin.close();
        fin.close();
        bout.close();
        fout.close();
    }
}

第二步在文章中是这样描述的:

分析提取出来的数据文件,使用WinHex查看其16进制代码。由于Jar文件的开头总是PK开头,并且总包含有manifest.mf文件,并且结尾总是有3个00,同时结尾段有整个Jar包文件的索引,我们可以根据这一特性来分析我们需要的片段。
1、搜索Jar的manifest,然后往前找,找到的第一个PK段,即为一个Jar的开头。
2、查看片段里Jar里的每个class信息,直到最后的文件索引片段。
3、一个Jar的结束片段位于索引片段之后,仍然包含着PK段,并且最后包含着3个00,且这3个00距离PK大概20个字节左右
根据以上3条准则,足以提取整个Jar数据段,然后导入新文件中,并且以zip字段命名,尝试用ZIP解压缩软件打开,看看是否抽取正确。

这个步骤需要不断尝试才能得到正确的文件,通过实践发现有更简单的方法:在解码后的文件中,如果包含多个jar文件,则之间用十六进制88分隔,每个jar文件均以PK开始,因此可以在WinHex中这样操作:

搜索十六进制串:88888888504B03040A00,其中前面的88分隔符可以根据需要调整数量,将找到的PK(504B)标注为块的开始,按F3再次搜索此特征串,从找到的下一个位置处往前搜索到第一个非88的字节作为块的结束,然后在Edit|Block中将选中的块插入到新文件即可,现在找到的PK的位置即为下一个jar文件的开始。依次类推,可分离出所有的jar文件,注意:最后一个jar文件的结束是PK200 (即jar文件所使用的压缩算法)。

经过实践,这个方法能快速地找到并分离exe4j打包的exe文件中的jar文件。

更简单的方法是:

打包成可执行文件的Java程序在运行时,会将jar全部解压然后调用java运行库执行,只要到系统temp文件夹中搜索*.jar即可得到。