package mobi.acpm.inspeckage.hooks;
import android.content.ContextWrapper;
import java.io.File;
import java.io.FileInputStream;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.Set;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XSharedPreferences;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import mobi.acpm.inspeckage.Module;
import mobi.acpm.inspeckage.util.FileType;
import mobi.acpm.inspeckage.util.FileUtil;
import static de.robv.android.xposed.XposedHelpers.findAndHookConstructor;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
import static de.robv.android.xposed.XposedHelpers.getObjectField;
/**
* Created by acpm on 17/11/15.
*/
public class SharedPrefsHook extends XC_MethodHook {
public static final String TAG = "Inspeckage_Prefs:";
static StringBuffer sb = null;
private static XSharedPreferences sPrefs;
public static String putFileName = "";
public static void loadPrefs() {
sPrefs = new XSharedPreferences(Module.class.getPackage().getName(), Module.PREFS);
sPrefs.makeWorldReadable();
}
public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) {
loadPrefs();
findAndHookMethod(ContextWrapper.class, "getSharedPreferences",
String.class, "int", new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
int modeId = (Integer) param.args[1];
String mode = "MODE_PRIVATE";
if(modeId == 1){
mode = "MODE_WORLD_READABLE";
}else if(modeId == 2){
mode = "MODE_WORLD_WRITEABLE";
}else if(modeId > 2){
mode = "APPEND or MULTI_PROCESS";
}
sb = new StringBuffer();
//sb.append("PUT[" + (String) param.args[0] + ".xml , "+mode+"]");
putFileName = "PUT[" + (String) param.args[0] + ".xml , "+mode+"]";
}
});
//SharedPreferences é interface, o xposed só trabalha com class
findAndHookConstructor("android.app.SharedPreferencesImpl", loadPackageParam.classLoader, File.class, "int", new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
File mFile = (File) param.args[0];
String text = "";
if (mFile.exists() && mFile.canRead()) {
FileInputStream f = new FileInputStream(mFile);
FileChannel ch = f.getChannel();
MappedByteBuffer mbb = ch.map(FileChannel.MapMode.READ_ONLY, 0L, ch.size());
while (mbb.hasRemaining()) {
String charsetName = "UTF-8";
CharBuffer cb = Charset.forName(charsetName).decode(mbb);
text = cb.toString();
}
}
FileUtil.writeToFile(sPrefs, text, FileType.PREFS_BKP, mFile.getName());
}
});
findAndHookMethod("android.app.SharedPreferencesImpl.EditorImpl", loadPackageParam.classLoader, "commit",
new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
if (sb.toString().length() > 0)
XposedBridge.log(TAG + "" + sb.toString().substring(0, sb.length() - 1) + "");
sb = new StringBuffer();
}
});
findAndHookMethod("android.app.SharedPreferencesImpl.EditorImpl", loadPackageParam.classLoader, "apply",
new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
if (sb.toString().length() > 0)
XposedBridge.log(TAG + "" + sb.toString().substring(0, sb.length() - 1) + "");
sb = new StringBuffer();
}
});
//***********GET************//
findAndHookMethod("android.app.SharedPreferencesImpl", loadPackageParam.classLoader, "getString",
String.class, String.class, new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
File f = (File) getObjectField(param.thisObject, "mFile");
XposedBridge.log(TAG + "GET[" + f.getName() + "] String(" + (String) param.args[0] + " , " + (String) param.getResult() + ")");
}
});
findAndHookMethod("android.app.SharedPreferencesImpl", loadPackageParam.classLoader, "getStringSet",
String.class, Set.class, new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
Set<String> set = (Set) param.getResult();
StringBuffer sb = new StringBuffer();
if (set != null && set.size() > 0)
for (String x : set) {
sb.append(x + "\n");
}
File f = (File) getObjectField(param.thisObject, "mFile");
XposedBridge.log(TAG + "GET[" + f.getName() + "] StringSet(" + (String) param.args[0] + ")= " + sb.toString() + ")");
}
});
findAndHookMethod("android.app.SharedPreferencesImpl", loadPackageParam.classLoader, "getBoolean",
String.class, "boolean", new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
File f = (File) getObjectField(param.thisObject, "mFile");
Module.sPrefs.reload();
String[] strReplace = Module.sPrefs.getString("prefs_replace", "").split(",");
String key = (String) param.args[0];
if (key.equals(strReplace[0])) {
param.setResult(strReplace[1]);
}
XposedBridge.log(TAG + "GET[" + f.getName() + "] Boolean(" + param.args[0] + " , " + String.valueOf(param.getResult()) + ")");
}
});
findAndHookMethod("android.app.SharedPreferencesImpl", loadPackageParam.classLoader, "getFloat",
String.class, "float", new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
File f = (File) getObjectField(param.thisObject, "mFile");
XposedBridge.log(TAG + "GET[" + f.getName() + "] Float(" + (String) param.args[0] + " , " + Float.toString((float) param.getResult()) + ")");
}
});
findAndHookMethod("android.app.SharedPreferencesImpl", loadPackageParam.classLoader, "getInt",
String.class, "int", new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
File f = (File) getObjectField(param.thisObject, "mFile");
XposedBridge.log(TAG + "GET[" + f.getName() + "] Int(" + (String) param.args[0] + " , " + Integer.toString((int) param.getResult()) + ")");
}
});
findAndHookMethod("android.app.SharedPreferencesImpl", loadPackageParam.classLoader, "getLong",
String.class, "long", new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
File f = (File) getObjectField(param.thisObject, "mFile");
XposedBridge.log(TAG + "GET[" + f.getName() + "] Long(" + (String) param.args[0] + " , " + Long.toString((Long) param.getResult()) + ")");
}
});
findAndHookMethod("android.app.SharedPreferencesImpl", loadPackageParam.classLoader, "contains",
String.class, new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
File f = (File) getObjectField(param.thisObject, "mFile");
XposedBridge.log(TAG + "CONTAINS[" + f.getName() + "](" + (String) param.args[0] + " , " + Boolean.toString((boolean) param.getResult()) + ")");
}
});
//********PUT*********//
findAndHookMethod("android.app.SharedPreferencesImpl.EditorImpl", loadPackageParam.classLoader, "putString",
String.class, String.class, new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
sb.append(putFileName+" String(" + (String) param.args[0] + "," + (String) param.args[1] + "),");
}
});
findAndHookMethod("android.app.SharedPreferencesImpl.EditorImpl", loadPackageParam.classLoader, "putBoolean",
String.class, "boolean", new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
sb.append(putFileName+" Boolean(" + (String) param.args[0] + "," + String.valueOf(param.args[1]) + "),");
}
});
findAndHookMethod("android.app.SharedPreferencesImpl.EditorImpl", loadPackageParam.classLoader, "putInt",
String.class, "int", new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
sb.append(putFileName+" Int(" + (String) param.args[0] + "," + Integer.toString((Integer) param.args[1]) + "),");
}
});
findAndHookMethod("android.app.SharedPreferencesImpl.EditorImpl", loadPackageParam.classLoader, "putLong",
String.class, "long", new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
sb.append(putFileName+" Long(" + (String) param.args[0] + "," + Long.toString((Long) param.args[1]) + "),");
}
});
findAndHookMethod("android.app.SharedPreferencesImpl.EditorImpl", loadPackageParam.classLoader, "putFloat",
String.class, "float", new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
sb.append(putFileName+" Float(" + (String) param.args[0] + "," + Float.toString((Float) param.args[1]) + "),");
}
});
}
}