首页
论坛
课程
招聘
[原创]安卓实现内存漫游&Xposed逆向必备~
2021-8-26 18:04 8687

[原创]安卓实现内存漫游&Xposed逆向必备~

2021-8-26 18:04
8687

前言:

一个安卓原生方法实现内存漫游的功能对象。

之前在摸索了很久,后来在heap.cc里面根据方法名字发现的。具体实现如下。

9.0以下挺大的实现难度挺大的,需要通过Debug调试模式去发送对应的调试指令,才可以实现。

但是9.0原生的可以直接通过原生API实现。具体使用参考下方。感觉不错的还希望留个言支持一下。

/**
 * @author Zhenxi on 2021/5/5
 *
 * 源码参考:
 * http://androidxref.com/9.0.0_r3/s?refs=ClassD&project=art
 */
public class ChooseUtils {

    private static final Method startMethodTracingMethod;
    private static final Method stopMethodTracingMethod;
    private static final Method getMethodTracingModeMethod;
    private static final Method getRuntimeStatMethod;
    private static final Method getRuntimeStatsMethod;
    private static final Method countInstancesOfClassMethod;
    private static final Method countInstancesOfClassesMethod;

    private static  Method getInstancesOfClassesMethod ;

    static {
        try {
            Class<?> c = Class.forName("dalvik.system.VMDebug");
            startMethodTracingMethod = c.getDeclaredMethod("startMethodTracing", String.class,
                    Integer.TYPE, Integer.TYPE, Boolean.TYPE, Integer.TYPE);
            stopMethodTracingMethod = c.getDeclaredMethod("stopMethodTracing");
            getMethodTracingModeMethod = c.getDeclaredMethod("getMethodTracingMode");
            getRuntimeStatMethod = c.getDeclaredMethod("getRuntimeStat", String.class);
            getRuntimeStatsMethod = c.getDeclaredMethod("getRuntimeStats");

            countInstancesOfClassMethod = c.getDeclaredMethod("countInstancesOfClass",
                    Class.class, Boolean.TYPE);


            countInstancesOfClassesMethod = c.getDeclaredMethod("countInstancesOfClasses",
                    Class[].class, Boolean.TYPE);

            //android 9.0以上才有这个方法
            if(android.os.Build.VERSION.SDK_INT>=28) {
                getInstancesOfClassesMethod = c.getDeclaredMethod("getInstancesOfClasses",
                        Class[].class, Boolean.TYPE);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 根据Class获取当前进程全部的实例
     *
     * @param clazz 需要查找的Class
     * @return 当前进程的全部实例。
     */
    @TargetApi(28)
    public static ArrayList<Object> choose(Class clazz) {
        return choose(clazz, false);
    }

    /**
     * 根据Class获取当前进程全部的实例
     *
     * @param clazz      需要查找的Class
     * @param assignable 是否包含子类的实例
     * @return 当前进程的全部实例。
     */
    @TargetApi(28)
    public static synchronized ArrayList<Object> choose(Class clazz, boolean assignable) {
        ArrayList<Object> resut = null;
        try {
            Object[][] instancesOfClasses = getInstancesOfClasses(new Class[]{clazz}, assignable);
            if (instancesOfClasses != null) {
                resut = new ArrayList<>();
                for (Object[] instancesOfClass : instancesOfClasses) {
                    resut.addAll(Arrays.asList(instancesOfClass));
                }
            }
        } catch (Throwable e) {
            Log.e(Constants.TAG,"ChooseUtils choose error ", e);
            e.printStackTrace();
        }
        return resut;
    }

    @TargetApi(28)
    private static Object[][] getInstancesOfClasses(Class<?>[] classes,
                                                    boolean assignable)
            throws Exception {
        return (Object[][]) getInstancesOfClassesMethod.invoke(
                null, new Object[]{classes, assignable});
    }

    public static void startMethodTracing(String filename, int bufferSize, int flags,
                                          boolean samplingEnabled, int intervalUs) throws Exception {
        startMethodTracingMethod.invoke(null, filename, bufferSize, flags, samplingEnabled,
                intervalUs);
    }

    public static void stopMethodTracing() throws Exception {
        stopMethodTracingMethod.invoke(null);
    }

    public static int getMethodTracingMode() throws Exception {
        return (int) getMethodTracingModeMethod.invoke(null);
    }

    /**
     *  String gc_count = VMDebug.getRuntimeStat("art.gc.gc-count");
     *  String gc_time = VMDebug.getRuntimeStat("art.gc.gc-time");
     *  String bytes_allocated = VMDebug.getRuntimeStat("art.gc.bytes-allocated");
     *  String bytes_freed = VMDebug.getRuntimeStat("art.gc.bytes-freed");
     *  String blocking_gc_count = VMDebug.getRuntimeStat("art.gc.blocking-gc-count");
     *  String blocking_gc_time = VMDebug.getRuntimeStat("art.gc.blocking-gc-time");
     *  String gc_count_rate_histogram = VMDebug.getRuntimeStat("art.gc.gc-count-rate-histogram");
     *  String blocking_gc_count_rate_histogram =VMDebug.getRuntimeStat("art.gc.gc-count-rate-histogram");
     */
    public static String getRuntimeStat(String statName) throws Exception {
        return (String) getRuntimeStatMethod.invoke(null, statName);
    }

    /**
     * 获取当前进程的状态信息
     */
    public static Map<String, String> getRuntimeStats() throws Exception {
        return (Map<String, String>) getRuntimeStatsMethod.invoke(null);
    }

    public static long countInstancesofClass(Class<?> c, boolean assignable) throws Exception {
        return (long) countInstancesOfClassMethod.invoke(null, new Object[]{c, assignable});
    }

    public static long[] countInstancesofClasses(Class<?>[] classes, boolean assignable)
            throws Exception {
        return (long[]) countInstancesOfClassesMethod.invoke(
                null, new Object[]{classes, assignable});
    }


}





2021 KCTF 秋季赛 防守篇-征题倒计时(11月14日截止)!

收藏
点赞8
打赏
分享
最新回复 (19)
雪    币: 133
活跃值: 活跃值 (321)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
koflfy 活跃值 1 2021-8-26 18:07
2
0
大佬666
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_zccmmjmn 活跃值 2021-8-26 18:24
3
0
不愧是大佬
雪    币: 1426
活跃值: 活跃值 (3501)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
supperlitt 活跃值 2021-8-26 18:25
4
0
tql
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_tronalmy 活跃值 2021-8-26 18:29
5
0
真棒
雪    币: 117
活跃值: 活跃值 (713)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
huaerxiela 活跃值 2021-8-26 19:41
6
0
不愧是大佬
雪    币: 232
活跃值: 活跃值 (453)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
juziss 活跃值 2021-8-26 20:06
7
0
大佬就是大佬
雪    币: 375
活跃值: 活跃值 (227)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
百事可乐就好 活跃值 2021-8-26 22:38
8
0
太强了
雪    币: 321
活跃值: 活跃值 (338)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
院士 活跃值 2021-8-27 07:54
9
0
啥叫内存漫游呢?
雪    币: 27
活跃值: 活跃值 (320)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
呼吸24K纯氧 活跃值 2021-8-28 21:06
10
0
试了一下,这个真的不错
雪    币: 683
活跃值: 活跃值 (2932)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
珍惜Any 活跃值 2021-8-29 11:27
11
0
呼吸24K纯氧 试了一下,这个真的不错[em_63]
感谢支持,我自己摸索也花了很久才找到。
雪    币: 1205
活跃值: 活跃值 (2927)
能力值: ( LV8,RANK:141 )
在线值:
发帖
回帖
粉丝
Simp1er 活跃值 2021-8-29 14:03
12
0
珍惜666
雪    币: 309
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
SomeMx 活跃值 2021-9-4 07:04
13
0
支持一下大佬!
雪    币: 220
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
CodeLeo 活跃值 2021-9-6 15:13
14
0
还需要绕开 hide api
雪    币: 683
活跃值: 活跃值 (2932)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
珍惜Any 活跃值 2021-9-7 18:11
15
0
CodeLeo 还需要绕开 hide api

TagSdk版本别太高就可以了,或者直接双重反射绕过。

最后于 2021-9-7 18:59 被珍惜Any编辑 ,原因:
雪    币: 3
活跃值: 活跃值 (1415)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
不吃早饭 活跃值 2021-9-7 18:27
16
0
珍惜Any ..... 这是公开api 而不是私有的,知识学杂了?

谦虚是一种美德

雪    币: 683
活跃值: 活跃值 (2932)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
珍惜Any 活跃值 2021-9-7 18:47
17
0
不吃早饭 谦虚是一种美德


我之前测试没问题的,在tagSDK 28以上 ,是因为edxp的问题,自带了绕过反射限制。确实需要绕过。tagsdk别太高就好啦

最后于 2021-9-7 19:15 被珍惜Any编辑 ,原因:
雪    币: 3
活跃值: 活跃值 (1415)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
不吃早饭 活跃值 2021-9-7 19:25
18
0
珍惜Any 不吃早饭 谦虚是一种美德 我之前测试没问题的,在tagSDK 28以上 ,是因为edxp的问题,自带了绕过反射限制。确实需要绕过。tagsdk别 ...

鸿蒙2.0,android10.0,targetSdk 30

雪    币: 683
活跃值: 活跃值 (2932)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
珍惜Any 活跃值 2021-9-7 19:36
19
0
不吃早饭 鸿蒙2.0,android10.0,targetSdk 30
确实会挂,之前没挂是edxp的问题,tag版本低一点就行了。
雪    币: 1870
活跃值: 活跃值 (2752)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
virjar 活跃值 1 2021-9-7 19:44
20
0
反射绕过也是一个风控对抗点
游客
登录 | 注册 方可回帖
返回