记录一次失败需求的经历, hack 终究是不归路。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
jeesk
V2EX    Android

记录一次失败需求的经历, hack 终究是不归路。

  •  1
     
  •   jeesk 2024-06-06 21:56:45 +08:00 8206 次点击
    这是一个创建于 494 天前的主题,其中的信息可能已经有所发展或是发生改变。

    首先我们有个需求, 就是能够在 WebView 中适配控制 media 的播放控制, 但是查看 api 发现,webview 根本没有暴露 mediasssion 这方面的 api. 怎么办? 只能去看看源码。

    通过搜索, 发现 chromium 项目中有 MediaSession 这个接口,然后找到了这个类的实现 org.chromium.content.bowser.MediaSessionImpl

    ,发现这个类有一个静态方法。

    @CalledByNative private static MediaSessionImpl create(long nativeMediaSession), 这个时候肯定是 native 调用了 java 的代码。 

    那么继续搜索 MediaSessionImpl_create 在 chromium 源码中, 继续搜索

     src git:(123.0.6312.121) grep -rn "MediaSessionImpl" --include="*.cc" |grep create content/browser/media/session/media_session_android.cc:38: Java_MediaSessionImpl_create(env, reinterpret_cast<intptr_t>(this)); 

    继续往下面看

    MediaSessionAndroid::MediaSessionAndroid(MediaSessionImpl* session) : media_session_(session) { DCHECK(media_session_); JNIEnv* env = base::android::AttachCurrentThread(); ScopedJavaLocalRef<jobject> j_media_session = Java_MediaSessionImpl_create(env, reinterpret_cast<intptr_t>(this)); j_media_session_ = JavaObjectWeakGlobalRef(env, j_media_session); WebContentsImpl* cOntents= static_cast<WebContentsImpl*>(media_session_->web_contents()); if (contents) { web_contents_android_ = contents->GetWebContentsAndroid(); DCHECK(web_contents_android_); web_contents_android_->SetMediaSession(j_media_session); } session->AddObserver(observer_receiver_.BindNewPipeAndPassRemote()); } 

    发现了 mediaSession 被设置到 WebContents, 通过搜索发现 WebContents 是一个接口, 继续找到该类的子类 WebContentsImpl.java , 发现里面有一行代码

     @CalledByNative private final void setMediaSession(MediaSessionImpl mediaSession) { mMediaSession = mediaSession; } 

    , 哈哈惊喜过度, 对象 mediaSession 竟然还在。 那还不简单, 直接通过反射去拿这个对象?

    这里直接反射的过程简单说一下, 首先我们通过 WebView 的 classloader 拿到 WebView 的 Class 对象 ,再反射拿到 WebView 类里面的 mProvider 对象, 这个 mProdiver 其实就是 WebViewChromium.java, 在通过 WebViewChromium.java 对象里面的 AwContents 拿到对象 WebContens ,找到 WebContens 对象后, 就能反射拿到 mediaSession 了, 这个里面有很多坑,反射通过字段很多拿不到,名字和类名被混淆了,所以需要写很多 hack 代码。

    这个时候直接反射出了 mMediaSession , 但是发现这个字段怎么都不存在, 惊呆了我的下巴, 继续测试,发现 setMediaSession 这个方法存在的。 这是怎么回事儿了? 二进制和源代码不一致? 这个时候不得不使用一些反编译工具了, 反编译出 MediaSessionImpl.java 文件,发现 mMediaSession 字段不存在, 并且 mMediaSession = mediaSession; 代码也消失了。

    这这这这这? 心里一万个草泥马。 经过多次测试,发现这段代码被编译器忽略掉了。

    认真分析 media_session_android.cc , 发现 setMediaSession 这个方法肯定是调用了的。 这个时候又去查询了一些资料,发现 native 方法的调用的原理是反射, 这个时候就只能去修改 classloader 里面的 class 文件内容了, 奇奇怪怪的折腾。

    未完待续, 后面会继续分析。

    9 条回复    2024-06-07 17:55:32 +08:00
    anbus
        1
    anbus  
       2024-06-07 11:37:49 +08:00
    这么抽象的吗
    meteora0tkvo
        2
    meteora0tkvo  
       2024-06-07 11:52:52 +08:00
    hack chromium 内核这是在给后人留坑啊,后人一更新 app 里的 chromium 程序就崩了,除非你的 app 像小程序一样有深度定制内核需求
    jeesk
        3
    jeesk  
    OP
       2024-06-07 12:35:09 +08:00
    @z836454898 自己处理好兼容性就行了.
    jeesk
        4
    jeesk  
    OP
       2024-06-07 12:35:47 +08:00
    @anbus 没办法, 坑太多了. 只有像苹果这种闭源, hack 的可能性就很小
    jeesk
        5
    jeesk  
    OP
       2024-06-07 12:38:17 +08:00
    @z836454898 我们自己定制了内核. 不过有些场景不需要定制内核 , 主要是为了减少体积.
    HtPM
        6
    HtPM  
       2024-06-07 16:24:50 +08:00
    “这个时候直接反射出了 mMediaSession , 但是发现这个字段怎么都不存在, 惊呆了我的下巴, 继续测试,发现 setMediaSession 这个方法存在的”
    这句话什么意思?你是说反射出了 MediaSession 的这个对象,但是字段 mMediaSession 不存在?这正常啊,如果做了代码混淆,mMediaSession 不就不存在了?变成其它名称了
    HtPM
        7
    HtPM  
       2024-06-07 16:27:04 +08:00
    “认真分析 media_session_android.cc , 发现 setMediaSession 这个方法肯定是调用了的。 这个时候又去查询了一些资料,发现 native 方法的调用的原理是反射”
    还有这句话是什么意思?你是说 setMediaSession 这个 Java 函数是被 native 方法反射调用的?
    jeesk
        8
    jeesk  
    OP
       2024-06-07 17:54:44 +08:00
    @HtPM setMediaSession 就是被 native 代码调用了, native 如何知道调用哪个方法? 不就是使用反射吗?
    jeesk
        9
    jeesk  
    OP
       2024-06-07 17:55:32 +08:00
    @HtPM setMediaSession() 这个方法存在, 但是 里面的 this.mMediaSession = mediaSession; 和 private mMediaSession 代码被编译丢弃了.
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     956 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 20ms UTC 19:31 PVG 03:31 LAX 12:31 JFK 15:31
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86