基于Jad的批量反编译工具JarDecompiler

基于Jad的批量反编译工具JarDecompiler
       最近因为工作需要反编译oracle的jdbc driver,用了frontend plus,发现无法编译整个jar,用起来比较繁琐。于是,狠狠心写了这个么个工具类,时间有限,没有什么设计思想,本着拿来就用的态度,很简陋的完成了这个小任务。 :) 基本思想是:能够编译指定目录下的所有jar文件,并将文件生成到指定的目录下,同时将所有的jad文件重名成java。


        这个工具依赖于jad, 所以需要预先安装。执行后会在outputDir下生成两个目录: unzip, decompile。用法如下:JarDecompiler <jadPath> [targetDir] [outputDir], 如果需要自定义的一些功能,大家可以根据Jad的一些option进行修改。因为基于runtime exec,我自己使用过程中发现,如过jar过多、过大的话,运行一边以后,发现并不是所有的文件都能反编译出来,可能需要连续执行几次才能将所有jar包编译完成。这个问题比较怪异,谁有兴趣的话,可以看看。中间还有生成bat文件的代码,不过代码太多的话,显得比较乱,被我去掉了,有兴趣的可以留下邮箱。


  1  package test.decompiler;
  2 
  3  import  java.io.File;
  4  import  java.io.IOException;
  5  import  java.util.jar.JarFile;
  6  import  java.util.jar.JarEntry;
  7  import  java.io.InputStream;
  8  import  java.io.FileOutputStream;
  9  import  java.io.DataOutputStream;
 10  import  java.util.ArrayList;
 11 
 12 
 13  public   class  JarDecompiler {
 14      
 15       private  String jadPath  =   null ;
 16       private  String targetDir  =   " . " ;
 17       private  String outputDir  =   " . " ;
 18       private  File unzipFile  =   null
 19       private   static  String UNZIP  =   " unzip " ;
 20       private   static  String DECOMPILE = " decompile " ;
 21      
 22       private  ArrayList jarFileList  =   null ;
 23       private  ArrayList dirList  =   null ;
 24       private  ArrayList fileList  =   null ;
 25      
 26 
 27       public  JarDecompiler(String jadPath, String targetDir, String outputDir) {
 28           //  TODO Auto-generated constructor stub
 29           this .jadPath  =  jadPath;
 30           if (targetDir  !=   null )
 31               this .targetDir  =  targetDir;
 32           if (outputDir  !=   null )
 33               this .outputDir  =  outputDir;
 34           this .outputDir  =   this .outputDir  +  System.getProperty( " file.separator " );
 35          jarFileList  =   new  ArrayList();
 36          dirList  =   new  ArrayList();
 37          fileList  =   new  ArrayList();
 38      }
 39 
 40       /**
 41       *  @param  args
 42        */
 43       public   static   void  main(String[] args) {
 44           //  TODO Auto-generated method stub
 45          JarDecompiler decompiler  =   null ;
 46           if ((args.length  <   1 ||  (args.length  >   3 ))
 47          {
 48              usage();
 49              System.exit( 1 );
 50          }
 51           else   if (args.length  == 1 )
 52              decompiler  =   new  JarDecompiler(args[ 0 ],  null null );
 53           else   if (args.length  == 2 )
 54              decompiler  =   new  JarDecompiler(args[ 0 ], args[ 1 ],  null );
 55           else   if (args.length  == 3 )
 56              decompiler  =   new  JarDecompiler(args[ 0 ], args[ 1 ], args[ 2 ]);
 57          decompiler.run();
 58      }
 59      
 60       public   void  run()
 61      {
 62           if (initializeFiles())
 63          {
 64              getJarFileNameList(targetDir);
 65               // printArrayList(jarFileList);
 66               for ( int  loop = 0 ; loop < jarFileList.size(); loop ++ )
 67              {
 68                  unzipJar((String)jarFileList.get(loop));                
 69              }
 70              getDirNameList(outputDir  +  UNZIP);
 71               // printArrayList(dirList);
 72              checkDir(outputDir  +  DECOMPILE);
 73              String dirName =   null ;
 74               for ( int  i = 0 ; i < dirList.size(); i ++ )
 75              {
 76                  dirName  =  (String)dirList.get(i);
 77                  dirName  =  dirName.replaceFirst(UNZIP, DECOMPILE);
 78                  checkDir(dirName);
 79              }
 80              decompile();
 81              getFileNameList(outputDir  +  DECOMPILE);
 82               // printArrayList(fileList);
 83              renameFiles();
 84               // printJarFiles();
 85              unzipFile.delete();
 86          }
 87      }
 88      
 89       private   void  printArrayList(ArrayList list)
 90      {
 91           for ( int  loop = 0 ; loop < list.size(); loop ++ )
 92          {
 93              System.out.println(list.get(loop));
 94          }        
 95      }
 96      
 97       private   boolean  initializeFiles()
 98      {
 99           boolean  ret  =   true ;
100          unzipFile  =   new  File(outputDir  +  UNZIP);
101          
102           if (unzipFile.exists())
103          {
104               // ret = false;
105              System.out.println(UNZIP  +   "  has been existed in  "   +  outputDir);
106          } else
107          {
108               try
109              {
110                  unzipFile.mkdir();
111              } catch (Exception e)
112              {
113                  e.printStackTrace();
114              }
115          }    
116           return  ret;
117      }
118      
119       private   void  getJarFileNameList(String targetDir)
120      {
121          File[] files  =   null ;
122          File target  =   new  File(targetDir);
123           if (target.exists()  &&  target.isDirectory())
124          {
125              files  =  target.listFiles();
126               for ( int  loop = 0 ; loop < files.length; loop ++ )
127              {
128                   if (files[loop].isFile()  &&  files[loop].getName().endsWith( " .jar " ))
129                  {
130                      jarFileList.add(files[loop].getAbsolutePath());
131                  } else   if (files[loop].isDirectory())
132                  {
133                      getJarFileNameList(files[loop].getAbsolutePath());
134                  }
135              }
136          }
137      }
138      
139       private   void  getDirNameList(String dirName)
140      {
141          File[] files  =   null ;
142          File target  =   new  File(dirName);
143           if (target.exists()  &&  target.isDirectory())
144          {
145              files  =  target.listFiles();
146               for ( int  loop = 0 ; loop < files.length; loop ++ )
147              {
148                   if (files[loop].isDirectory())
149                  {
150                      dirList.add(files[loop].getAbsolutePath());
151                      getDirNameList(files[loop].getAbsolutePath());
152                  }
153              }
154          }
155      }
156      
157       private   void  getFileNameList(String dirName)
158      {
159          File[] files  =   null ;
160          File target  =   new  File(dirName);
161           if (target.exists()  &&  target.isDirectory())
162          {
163              files  =  target.listFiles();
164               for ( int  loop = 0 ; loop < files.length; loop ++ )
165              {
166                   if (files[loop].isDirectory())
167                  {
168                      getFileNameList(files[loop].getAbsolutePath());
169                  } else   if (files[loop].isFile())
170                  {
171                      fileList.add(files[loop].getAbsolutePath());    
172                  }
173              }
174          }
175      }
176      
177       private    boolean  unzipJar(String fileName)
178      {
179           boolean  ret  =   true ;
180          String postfixName  =  fileName.substring(outputDir.length());
181          String zipTo  =  outputDir  +  UNZIP  +  System.getProperty( " file.separator " );
182          
183          Object[] dirs  =  getDirs(postfixName).toArray();
184          
185          checkDir(zipTo);
186           for ( int  loop = 0 ; loop < dirs.length; loop ++ )
187          {
188              zipTo  =  zipTo  +  (String)dirs[loop];
189               if (zipTo.endsWith( " .jar " ))
190              {
191                  zipTo.substring( 0 , zipTo.length()  - 4 );
192              }
193              zipTo  =  zipTo  +  System.getProperty( " file.separator " );
194              checkDir(zipTo);
195          }
196          
197           try
198          {
199              String cmd  =   " unzip -d  "   +  zipTo  +   "   "   +  fileName;
200              Runtime.getRuntime().exec(cmd);
201          } catch (IOException ioe)
202          {
203              ioe.printStackTrace();
204          }
205          
206           return  ret;
207      }
208      
209       public   void  decompile()
210      {
211          
212          String target  =   null ;
213          String output  =   null ;
214          String decopCmd  =   null ;
215          InputStream es  =   null ;
216 
217          Process decompP  =   null ;
218           int  result  =   - 1 ;
219           byte [] toRead  =   new   byte [ 2048 ];
220           for ( int  i = 0 ; i < dirList.size(); i ++ )
221          {
222              target  =  (String)dirList.get(i);
223              output  =  target;
224              output  =  output.replaceFirst(UNZIP, DECOMPILE);
225              decopCmd  =   " jad -ff -d  "   +  output  +   "   "   +  target  +  
226                  System.getProperty( " file.separator " +   " *.class " ;
227              decopCmd  =  jadPath  +  System.getProperty( " file.separator " +  decopCmd;
228              
229               // System.out.println(decopCmd);
230               try
231              {
232                  decompP  =  Runtime.getRuntime().exec(decopCmd);
233                  es  =  decompP.getErrorStream();
234                   /*
235                  while(es.read(toRead) > 0)
236                  {
237                      System.out.println(new String(toRead));
238                  }
239                   */
240              } catch (Exception e)
241              {
242                  e.printStackTrace();
243              }
244          }
245      }
246      
247      
248       private   void  renameFiles()
249      {
250          String target  =   null ;
251          String output  =   null ;
252          String renameCmd  =   null ;
253          File targetFile  =   null ;
254          File destFile  =   null ;
255          Process p  =   null ;
256          
257           for ( int  i = 0 ; i < fileList.size(); i ++ )
258          {
259               if (((String)fileList.get(i)).endsWith( " .jad " ))
260              {
261                  target  =  (String)fileList.get(i);
262                  output  =  target;
263                  output  =  output.replaceFirst(UNZIP, DECOMPILE);
264                  
265                  targetFile  =   new  File(output);
266                   // System.out.println("rename from: " + output + " to: " + output.substring(0, output.length() -4) + ".java");
267                  destFile  =   new  File(output.substring( 0 , output.length()  - 4 +   " .java " );
268                  targetFile.renameTo(destFile);
269                  targetFile.delete();
270                   try
271                  {
272                      Thread.currentThread().sleep( 100 );
273                  } catch (Exception e)
274                  {
275                      e.printStackTrace();
276                  }
277                  
278                   /*
279                  renameCmd = "cmd /c ren " + output + " " + output.substring(0, output.length() -4) + ".java";
280                  System.out.println(renameCmd);
281                  try
282                  {
283                      p = Runtime.getRuntime().exec(renameCmd);
284                      p.waitFor();
285                  }catch(Exception e)
286                  {
287                      e.printStackTrace();
288                  }
289                   */
290                  
291              }
292              targetFile  =   null ;
293              destFile  =   null ;
294          }
295      }
296      
297       private   void  checkDir(String name)
298      {
299          File file  =   new  File(name);
300           if ( ! file.exists())
301          {
302              file.mkdir();
303          }
304      }
305      
306       public  ArrayList getDirs(String name)
307      {
308          ArrayList list  =   new  ArrayList();
309           while (name.indexOf(System.getProperty( " file.separator " ))  !=   - 1 )
310          {
311              list.add(name.substring( 0 , name.indexOf(System.getProperty( " file.separator " ))));
312              name  =  name.substring(name.indexOf( System.getProperty( " file.separator " )) + 1 );
313          }
314          
315          list.add(name.substring( 0 , name.length() - 4 ));
316           return  list;
317      }
318      
319       private   static   void  usage()
320      {
321          System.out.println( " usage: java test.decompiler.JarDecompiler <Jad Path> [target Dir] [output Dir] " );
322      }
323 
324  }
325 


你可能感兴趣的:(基于Jad的批量反编译工具JarDecompiler)