如何 Hook 方法 Class.class.getResourceAsStream? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
ntdll
V2EX    Java

如何 Hook 方法 Class.class.getResourceAsStream?

  •  
  •   ntdll Oct 19, 2017 2059 views
    This topic created in 3114 days ago, the information mentioned may be changed or developed.

    起因

    leader 提的诡异需求,有一批旧项目,需要在一个 android 项目中使用。 使用场景是在 android 设备中通过网络下载这些 jar (已使用 dx --dex 转换 bytecode ),加载并启动。 但是由于环境的变化导致原项目中一些资源请求不存在,需要重定向。

    经过

    目前的做法是,在 android 项目中使用自定义 ClassLoader 加载这些 jar,并启动。 目前碰到的问题是由于旧项目中大量的使用了 Class.class.getResourceAsSteamthis.getClass().getResourceAsStream方法。

    后者由于是通过我自定义的 ClassLoader 加载, 因此调用请求会被委托到我自定义 ClassLoader 的 getResourceAsStream 方法上。没有问题。

    问题就在于Class.class.getResourceAsSteam这样的调用,由于双亲委派,是由 Boot ClassLoader 加载。 因此我无法重定向这些资源请求。

    尝试过这些方案:

    • 自定义 ClassLoader,不执行双亲委派原则。但是此时我的自定义 ClassLoader 无法加载系统类的.jar 文件。提示 refusing reopen framework .....(filename)
    • 在自定义 ClassLoader 中,尝试通过双亲委派获得的 Class 对象,通过反射修改其 classloader 对象。[失败]原因不明,提示找不到 classloader 对应的字段。通过Field.getDeclaredFields()方法,也确实没有该属性

    求结果

    目前需要的效果是,可以通过各种奇技淫巧(不包括修改旧项目的源代码),重定向这些代码中的类似 String/Class/System.clsss.getResourceAsStream方法的调用。

    感谢各位能够提供解决方法或者思路的。

    Supplement 1    Oct 20, 2017

    @cppgohan @sutra 再次尝试过这些方法

    • 将java.boot.class.path的所有文件复制到程序内部
    • 自定义ClassLoader加载程序内部的java.boot.class.path副本,并丢弃双亲委派机制

    自定义类加载器逻辑:

    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { Class clazz = this.findLoadedClass(name); if (clazz == null) { clazz = this.findClass(name); } } return clazz } 

    但是依旧失败。在自定义ClassLoader下,确实实现了与宿主环境完全隔离,但是当我加载自己的类的出现了异常 dalvikvm: (LDemoActivity; had used a different Landroid/app/Activity; during pre-verification) 对于这个异常,我不是很理解,因为整个对象是在我自己的ClassLoader下加载,应该不会出现这个问题。

    这个异常说明在我的类加载器下,依旧返回了宿主环境的Activity类。

    苦于一直找不到原因,因此在自己的类加载器中做了区别对待:

     clazz = this.findLoadedClass(name); if (clazz == null) { if (name.startsWith("android.")) { clazz = super.loadClass(name, resolve); Log.i(TAG, "successfully parent load class " + name); } else { clazz = this.findClass(name); Log.i(TAG, "successfully self load class " + name); } } 

    这样固然可以正常启动,但是由于Activity和其他类的ClassLoader不同,造成大量的类型不匹配,因此也无法跑起来。这就说明,在类加载的验证阶段,期待的是宿主环境下的Activity类,而实际上获得是隔离环境下的Activity类。

    那么现在的问题就是当我使用自己的类加载器,调用loadClass方法尝试加载DemoActivity时,为何在验证环境其父类会变成要求是宿主环境的Activity类?根据我的理解,此时自定义ClassLoader并未加载Activity类,上下文中也不存在Activity(由于ClassLoader产生的隔离环境),不应该抛出这样的异常。

    求大佬科普

    3 replies    2017-10-23 15:45:32 +08:00
    cppgohan
        1
    cppgohan  
       Oct 20, 2017
    关注一下, 总觉得用反射修改 classloader 应该是可以一试的.. 不知道为什么会找不到
    sutra
        2
    sutra  
       Oct 20, 2017
    在 classpath 里给它那个 resource,用符号链接,不知道行不行。
    teemoer
        3
    teemoer  
       Oct 23, 2017
    xposed (手动滑稽)
    About     Help     Advertise     Blog     API     FAQ     Solana     5462 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 68ms UTC 08:37 PVG 16:37 LAX 01:37 JFK 04:37
    Do have faith in what you're doing.
    ubao msn 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