Skip to content

Instantly share code, notes, and snippets.

@oasisfeng
Last active December 19, 2015 17:39
Show Gist options
  • Save oasisfeng/5993367 to your computer and use it in GitHub Desktop.
Save oasisfeng/5993367 to your computer and use it in GitHub Desktop.
Xposed module to patch Master-Key security vulnerability.
package com.oasisfeng.security.masterkeypatch;
import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import android.util.Log;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
/**
* Compiled app is available for download:
* https://play.google.com/store/apps/details?id=com.oasisfeng.security.masterkeypatch
*
* @author Oasis
*/
public class Xposed implements IXposedHookLoadPackage {
@Override public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
if (! "android".equals(lpparam.packageName)) return;
Log.i(TAG, "Patching Master-Key security vulnerability...");
// private void readCentralDir() throws IOException
XposedHelpers.findAndHookMethod(ZipFile.class, "readCentralDir", new XC_MethodHook() {
@Override protected void beforeHookedMethod(final MethodHookParam param) throws Throwable {
final ZipFile zipfile = (ZipFile) param.thisObject;
final Field field = ZipFile.class.getDeclaredField("mEntries");
field.setAccessible(true);
field.set(zipfile, new UnreplaceableLinkedHashMap<String, ZipEntry>());
}
@Override protected void afterHookedMethod(final MethodHookParam param) throws Throwable {
final Throwable throwable = param.getThrowable(), cause;
if (throwable instanceof IllegalStateException && (cause = throwable.getCause()) instanceof ZipException)
param.setThrowable(cause);
}
});
}
private static final String TAG = "MasterKeyPatch";
}
class UnreplaceableLinkedHashMap<K, V> extends LinkedHashMap<K, V> {
@Override public V put(final K key, final V value) {
if (super.put(key, value) != null)
throw new IllegalStateException(new ZipException("Duplicate entry name: " + key));
return null;
}
private static final long serialVersionUID = -2770000950350787563L;
}
@oasisfeng
Copy link
Author

Thanks for the suggestion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment