1 /* Backport - Bring New Fixes to old Androids 
   2  * Copyright (C) 2013  Jay Freeman (saurik) 
   5 /* GNU Lesser General Public License, Version 3 {{{ */ 
   7  * Substrate is free software: you can redistribute it and/or modify it under 
   8  * the terms of the GNU Lesser General Public License as published by the 
   9  * Free Software Foundation, either version 3 of the License, or (at your 
  10  * option) any later version. 
  12  * Substrate is distributed in the hope that it will be useful, but WITHOUT 
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
  15  * License for more details. 
  17  * You should have received a copy of the GNU Lesser General Public License 
  18  * along with Substrate.  If not, see <http://www.gnu.org/licenses/>. 
  22 package com
.saurik
.backport
; 
  24 import java
.lang
.reflect
.Field
; 
  25 import java
.lang
.reflect
.Method
; 
  27 import java
.util
.LinkedHashMap
; 
  29 import java
.util
.jar
.JarFile
; 
  31 import java
.util
.zip
.ZipEntry
; 
  32 import java
.util
.zip
.ZipException
; 
  33 import java
.util
.zip
.ZipFile
; 
  35 import android
.util
.Log
; 
  37 import com
.saurik
.substrate
.MS
; 
  40     private static class WrongException
 
  41         extends RuntimeException
 
  43         public WrongException(Throwable cause
) { 
  48     public static void initialize() { 
  49         MS
.hookClassLoad("java.util.zip.ZipFile", new MS
.ClassLoadHook() { 
  50             public void classLoaded(Class
<?
> ZipFile$
) { 
  51                 Field entries 
= null; { 
  52                     if (entries 
== null) try { 
  53                         entries 
= ZipFile$
.getDeclaredField("entries"); 
  54                     } catch (NoSuchFieldException e
) {} 
  56                     if (entries 
== null) try { 
  57                         entries 
= ZipFile$
.getDeclaredField("mEntries"); 
  58                     } catch (NoSuchFieldException e
) {} 
  63                 final Field ZipFile$entries 
= entries
; 
  64                 ZipFile$entries
.setAccessible(true); 
  66                 final Method ZipFile$readCentralDir
; try { 
  67                     ZipFile$readCentralDir 
= ZipFile$
.getDeclaredMethod("readCentralDir"); 
  68                 } catch (NoSuchMethodException e
) { 
  69                     Log
.e("Backport", "ZipFile$readCentralDir", e
); 
  73                 MS
.hookMethod(ZipFile$
, ZipFile$readCentralDir
, 
  74                     new MS
.MethodAlteration
<ZipFile
, Void
>() { 
  75                         public Void 
invoked(ZipFile thiz
, Object
... args
) 
  78                             ZipFile$entries
.set(thiz
, new LinkedHashMap
<String
, ZipEntry
>() { 
  79                                 public ZipEntry 
put(String key
, ZipEntry value
) { 
  80                                     if (super.put(key
, value
) != null) 
  81                                         throw new WrongException(new ZipException("Duplicate entry name: " + key
)); 
  87                                 return invoke(thiz
, args
); 
  88                             } catch (WrongException wrong
) { 
  89                                 throw wrong
.getCause();