0x0 背景

自从参加实习工作后,博客也没怎么更新了。。。(就是懒了)

最近在空闲时间撸了一个 Xposed 模块,用来修改Pokémon GO的定位坐标的。这个模块的思路来源于这篇文章 ,因为乌云平台炸了,不知道何时恢复,因此可能暂时访问不了。这个模块有用户界面用于存储配置信息,但是在读取时使用 Xposed 自带的XSharedPreferences却出现读取不了的问题。今天写一记录一下在使用XSharedPreferences读取数据时遇到的坑点。

0x1 过程

最开始的时候我在写配置的时候使用的是PreferenceManager.getDefaultSharedPreferences(),在 XposedhandleLoadPackage()方法中hook本程序的getApplicationContext()方法去拿到 context,再使用context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_WORLD_READABLE)方法拿到Preferences,但是在使用它读取时无法读取到。而且这种方法即使可以也有个缺陷,就是每次使用前都要打开这个应用进行初始化,身为一个 xp 模块怎么能这么不中用呢!

转去 Google 发现,XposedBridge本身提供了一个类 : XSharedPreferences针对这种情况进行配置文件读取~

好咧,开工写代码 XSharedPreferences preferences = new XSharedPreferences(BuildConfig.APPLICATION_ID); 然而。。。。

仍然获取不到数据。。。

继续翻文档,我发现好像忽略了点什么,点开getDefaultSharedPreferences()方法的源码得知,它最后调用了getSharedPreferences(name, Content.MODE_PRIVATE)这个方法,也就是说生成的文件是私有的,而 Xposed 模块里的代码是hook 到 Andrioid 虚拟机那里,在目标 app 打开时调用的,所以MODE_PRIVATE肯定不能读取到,应该改为MODE_WORLD_READABLE

OK,继续尝试,界面上的 Preferences 获取方法改成了preferences = getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_WORLD_READABLE),再次运行,还是不行!!!

WTF!!!

adb shell ,cd 到安装目录找到配置文件,文件名称是包名.xml,运行目标程序之后,当前目录下又多了个包名_prefs.xml文件。。

2016-07-25_2016548158703.jpg

0x2 总结

所以说,原因就是两边的文件名不同。

  • PACKAGE_NAME_prefs.xml:

    1
    2
    PreferenceManager.getDefaultSharedPreferences(context);
    XSharedPreferences(PACKAGE_NAME);
  • name.xml:

    1
    2
    context.getSharedPreferences(name, MODE);
    XSharedPreferences(PACKAGE_NAME, name);

以上~