Initial version of Backport to go with my article.
[backport.git] / src / com / saurik / backport / Hook.java
1 /* Backport - Bring New Fixes to old Androids
2 * Copyright (C) 2013 Jay Freeman (saurik)
3 */
4
5 /* GNU Lesser General Public License, Version 3 {{{ */
6 /*
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.
11 *
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.
16 *
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/>.
19 **/
20 /* }}} */
21
22 package com.saurik.backport;
23
24 import java.lang.reflect.Field;
25 import java.lang.reflect.Method;
26
27 import java.util.LinkedHashMap;
28
29 import java.util.jar.JarFile;
30
31 import java.util.zip.ZipEntry;
32 import java.util.zip.ZipException;
33 import java.util.zip.ZipFile;
34
35 import android.util.Log;
36
37 import com.saurik.substrate.MS;
38
39 public class Hook {
40 public static void initialize() {
41 MS.hookClassLoad("java.util.zip.ZipFile", new MS.ClassLoadHook() {
42 public void classLoaded(Class<?> ZipFile$) {
43 Field entries = null; {
44 if (entries == null) try {
45 entries = ZipFile$.getDeclaredField("entries");
46 } catch (NoSuchFieldException e) {}
47
48 if (entries == null) try {
49 entries = ZipFile$.getDeclaredField("mEntries");
50 } catch (NoSuchFieldException e) {}
51 }
52
53 if (entries == null)
54 return;
55 final Field ZipFile$entries = entries;
56 ZipFile$entries.setAccessible(true);
57
58 final Method ZipFile$readCentralDir; try {
59 ZipFile$readCentralDir = ZipFile$.getDeclaredMethod("readCentralDir");
60 } catch (NoSuchMethodException e) {
61 Log.e("Backport", "ZipFile$readCentralDir", e);
62 return;
63 }
64
65 MS.hookMethod(ZipFile$, ZipFile$readCentralDir,
66 new MS.MethodAlteration<ZipFile, Void>() {
67 public Void invoked(ZipFile thiz, Object... args)
68 throws Throwable
69 {
70 ZipFile$entries.set(thiz, new LinkedHashMap<String, ZipEntry>() {
71 public ZipEntry put(String key, ZipEntry value) {
72 if (super.put(key, value) != null)
73 throw new WrongException(new ZipException("Duplicate entry name: " + key));
74 return null;
75 }
76 });
77
78 return invoke(thiz, args);
79 }
80 }
81 );
82 }
83 });
84 }
85 }