完全屬於我自己的Blog,運行在我的路由器H218N上.記錄著我想記錄的文字.

2019年8月

08月 05

利用tcpdump抓取IPTV播放列表

之前抓取IPTV播放列表都是用Openwrt的端口镜像,配合台式机去抓包的,但是每次这样弄都好麻烦了,路由器,机顶盒,电脑都要用网线连接在一起,主力机变成XPS 15后,没有网口就显得更麻烦了。
此时就想起tcpdump了,这货不是能把所有数据包全抓下来吗,在路由器搞一搞就好了!
家里用的是软路由,弄个tcpdump还是很简单的,但是老人家里用的是K2P,还没硬改过的,装这个包和对应依赖空间有压力啊。。。
Google一番,没找到能用的tcpdump静态链接版本,又是DIY时刻了。
K2P刷的是高恪的固件,基于openwrt 14.07的,找到对应SDK和Toolchain,
参照之前的高恪插件编译教程弄起来了,却发现没有tcpdump这个包,搜索一番得知在base这个repo,SDK默认是没有添加这个repo的.

Openwrt 14.07也算是年代久远了,费劲一番才找到这个repo的源

git://git.archive.openwrt.org/14.07/openwrt.git

添加后就是常规操作

./script/feeds update
./script/feeds install

先按照官方动态链接的方式编译一遍看会不会出错。

make -j16 package/network/utils/tcpdump compile

成功编译后,看到依赖库libpcap把静态链接库也编译出来了。
接下来就是尝试编译静态链接的tcpdump了
只需要对Makefile稍作改动

  49 CONFIGURE_ARGS += \
  50         --without-crypto
  51 
  52 ifeq ($(CONFIG_IPV6),y)
  53 CONFIGURE_ARGS += \
  54         --enable-ipv6
  55 endif
  56 
  57 TARGET_CFLAGS += -ffunction-sections -fdata-sections
  58 TARGET_LDFLAGS += -Wl,--gc-sections
  59 
  60 CONFIGURE_VARS += \
  61         BUILD_CC="$(TARGET_CC)" \
  62         HOSTCC="$(HOSTCC)" \
  63         td_cv_buggygetaddrinfo="no" \
  64         ac_cv_linux_vers=$(LINUX_VERSION) \
  65         ac_cv_header_rpc_rpcent_h=no \
  66         ac_cv_lib_rpc_main=no \
  67         ac_cv_path_PCAP_CONFIG=""
  68 
  69 MAKE_FLAGS :=

改成

  49 CONFIGURE_ARGS += \
  50         --without-crypto
  51 
  52 ifeq ($(CONFIG_IPV6),y)
  53 CONFIGURE_ARGS += \
  54         --enable-ipv6
  55 endif
  56 
  57 TARGET_CFLAGS += -ffunction-sections -fdata-sections
  58 TARGET_LDFLAGS += -static -Wl,--gc-sections
  59 
  60 CONFIGURE_VARS += \
  61         BUILD_CC="$(TARGET_CC)" \
  62         HOSTCC="$(HOSTCC)" \
  63         td_cv_buggygetaddrinfo="no" \
  64         ac_cv_linux_vers=$(LINUX_VERSION) \
  65         ac_cv_header_rpc_rpcent_h=no \
  66         ac_cv_lib_rpc_main=no \
  67         ac_cv_path_PCAP_CONFIG=""
  68 
  69 MAKE_FLAGS :=

再次执行编译命令就可以了。

make -j16 package/network/utils/tcpdump compile

编译好的静态链接tcpdump和tcpdump-mini二进制附上。

在路由器上开始抓到包

tcpdump -i br-lan -s 0 -w iptv.pcap host 192.168.2.113

完了用scp把抓包文件传回到Mac上,直接用Charles就可以打开。
我这边都是rtsp协议的直播,所以直接查找关键词rtsp就可以找到列表页了,找到以后就是用正则提取一下电视台名称播放地址
查找关键词就找到播放列表页
用到的正则也很简单ChannelName="(.*?)".*ChannelURL="(?:.*?((?:rtsp|http).*?(?:smil|m3u8).*?END.*?))",最后就是根据个人习惯调整一下列表的顺序了。
广东电信这里抓到的播放列表在此

08月 05

记利用Xposed解除华为EMUI第三方桌面限制

自从入了魅族魅蓝E3的坑,等了一年也没等到BootLoader解锁的方法,也受够了那个没几秒就一次的WiFi断流。
苦苦寻觅,终于找到价格在2k上下,性能过得去,非异形屏,非背面指纹,拍照还可以,最重要一点,可以解锁BootLoader,可以装xposed的机子 -- 二手 华为 Mate 10。

机子到手随即在深水宝让人给解锁BootLoader了,开启了Magisk->Root->Xposed的折腾之路。

或许是距离我太久没碰过华为手机了(上一台华为手机还是C8850),发现刷入Magisk,安装Xposed的方法跟其他机型有很大区别,爬文了解了之后,算是把Magisk+Root+Xposed搞定了。

装上最熟悉的Nova Launcher却发现不能设置为默认桌面,华为什么脑残设定嘛!心想祭出冰箱冻结就好了,没想到事情却没这么简单,使用冰箱添加支付宝扫码快捷方式后,发现没有任何反应,冰箱的快捷方式权限已经给了啊!再去论坛爬文,发现还是华为脑残设定。。。这下子没这么好办了,冰箱管不到这块了。爬文良久没找到解决办法,只能硬着头皮自己来了。

既然默认应用设置把第三方桌面灰了不让我点,那就从这里入手,用开发者助手找出这里的资源ID,包名,将系统设置的apk传到Mac上JEB静态反编译走起。

第三方桌面被禁用
找出资源ID作为突破口

拿着0x7f0a07a8就到JEB去搜索,找到位于com.android.settings.applications.PreferredSettings这个类的onCreateView方法里,但是这个方法看不出什么有价值的线索,JEB字体太小,看的眼睛都疼了,还是把dex拉出来,用jadx直接把dex还原成Java源文件吧。
庆幸的是,这些代码并没有做混淆,还原成Java源文件后,方法名和变量名都是原始命名,这样看起来就容易多了。
7f0a07a8使用地方

用IntelliJ IDEA打开源码看,舒服多了,翻翻这个类,发现PreferredSettings.buildPreferredActivitiesList这个方法有点嫌疑,build什么List,可惜jadx反编译失败了,还是要回到jeb去看。Jeb反编译也不算很好,出来一堆goto,耐着性子找亮点。
发现这有重大嫌疑,Anti?Protection?Launcher?进去看看呗!
验证桌面权限
在这个类里,看到了华为桌面的包名com.huawei.android.launcher了,先写个hook,把AntiMalProtectionUtils.checkLauncherPermisson始终返回true试试!
华为桌面的包名

XposedBridge.hookAllMethods(loadPackageParam.classLoader.loadClass("com.android.settings.AntiMalProtectionUtils"), "checkLauncherPermisson", new XC_MethodHook() {
    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
        param.setResult(true);
    }
});

重启一看,红色提示文字消失了,第三方桌面可以选择了,但是应用快捷方式还是添加不了,常规返回Home时,还是回到的华为桌面。
难道跟AntiMalProtectionUtils.getHwDefLauncherPkg这个方法有关?

public static String getHwDefLauncherPkg() {
    return "com.huawei.android.launcher";
}

改成返回Nova桌面的包名试试?

XposedBridge.hookAllMethods(loadPackageParam.classLoader.loadClass("com.android.settings.AntiMalProtectionUtils"), "getHwDefLauncherPkg", new XC_MethodHook() {
    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
        param.setResult("com.teslacoilsw.launcher");
    }
});

结果还是不行,再仔细看AntiMalProtectionUtils.checkLauncherPermisson这个方法,按照它的正常流程走的话,ActivityManager.checkUidPermission应该要返回0,那就hook这个方法试试吧!

XposedBridge.hookAllMethods(loadPackageParam.classLoader.loadClass("android.app.ActivityManager"), "checkUidPermission", new XC_MethodHook() {
    @Override
    protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
        if (param.args[0] == "com.huawei.permission.sec.SDK_LAUNCHER")
            param.setResult(0);
    }
});

重启一试,成了!!!
反手就把华为桌面丢冰箱里了,没想到的是,这个老流氓,重启后竟然自动解冻了,还又成了默认桌面了!
这下就尴尬了,难道每次重启都要手动重新选一次桌面?这用户体验极差啊!
依稀记得看到过什么Launcher disabled之类的方法的,再翻翻去~~~
检测华为桌面被冻结

看到这个方法,解法很明显了,int res = this.mPm.getApplicationEnabledSetting(hwDefLauncherPkg);res的返回值不是23就好了。

XposedBridge.hookAllMethods(loadPackageParam.classLoader.loadClass("android.app.ApplicationPackageManager"), "getApplicationEnabledSetting", new XC_MethodHook() {
    @Override
    protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
        if (param.args[0] == "com.huawei.android.launcher")
            param.setResult(1);
    }
});

重启,设置Nova为默认桌面,冻结华为桌面,再重启,华为桌面没解冻了,默认桌面还是Nova,终于搞定了!
然而还是高兴的太早,屏幕手势的底部上滑失效了。。。
算了,我投降了。我不冻结华为桌面了,你一边凉快去吧。。。

最终达成效果:自由选择第三方桌面,自由使用Android 7开始的应用快捷方式。
随意选择桌面 随意选择桌面 开启应用快捷方式

完整Xposed源码在此