欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]FastHook——巧妙利用动态代理实现非侵入式AOP

[原创]FastHook——巧妙利用动态代理实现非侵入式AOP

一、概述

FastHook框架要求调用者准备与原方法参数一致的Hook方法和Forward方法,这些限制将业务逻辑和Hook逻辑耦合在一起。若不了解FastHook原理,请移步FastHook——一种高效稳定、简洁易用的Android Hook框架
因此可能需要一种新实现方式,其可将业务逻辑和Hook逻辑解耦。一种简单的方案便是动态生成Hook方法和Forword方法。然而该方案对性能的影响比较大,动态生成dex文件并加载是耗时操作。
本文将介绍一种新的思路,统一Hook方法,利用动态代理创建Forward方法。该方案比上述方案更加高效、简洁
Hook方案

二、Hook方法

Hook方法必须能实现以下两点需求
1. 能正确识别原方法
2. 能正确解析原方法参数

2.1 ART方法调用约定

以32位arm平台为例

    /*

     * Quick invocation stub internal.

     * On entry:

     *   r0 = method pointer

     *   r1 = argument array or null for no argument methods

     *   r2 = size of argument array in bytes

     *   r3 = (managed) thread pointer

     *   [sp] = JValue* result

     *   [sp + 4] = result_in_float

     *   [sp + 8] = core register argument array

     *   [sp + 12] = fp register argument array

     *  +-------------------------+

     *  | uint32_t* fp_reg_args   |

     *  | uint32_t* core_reg_args |

     *  |   result_in_float       | <- Caller frame

     *  |   Jvalue* result        |

     *  +-------------------------+

     *  |          lr             |

     *  |          r11            |

     *  |          r9             |

     *  |          r4             | <- r11

     *  +-------------------------+

     *  | uint32_t out[n-1]       |

     *  |    :      :             |        Outs

     *  | uint32_t out[0]         |

     *  | StackRef<ArtMethod>     | <- SP  value=null

     *  +-------------------------+

     */

1. r0寄存器存放被调用方法ArtMethod指针
2. r1~r3存放前3个参数
3. 从(sp+指针长度)地址起,按照参数顺序依次存放参数
显而易见,只需将被调用方法ArtMethod指针与sp指针传如Hook方法即可。32位指针长度为4字节,将以int类型传入,一种返回类型对应一个Hook方法

private static Object hookHandleObject(int targetArtMethod, int sp) {

    FastHookParam param = hookHandle(targetArtMethod,sp);

    return param.result;

}

private static boolean hookHandleBoolean(int targetArtMethod, int sp) {

    FastHookParam param = hookHandle(targetArtMethod,sp);

    if(param.result != null && param.result instanceof Boolean) {

            return ((Boolean) param.result).booleanValue();

        }    

    return false;

}

private static byte hookHandleByte(int targetArtMethod, int sp) {

    FastHookParam param = hookHandle(targetArtMethod,sp);

    if(param.result != null && param.result instanceof Byte) {

            return ((Byte) param.result).byteValue();

        }

        return 0;

}

private static char hookHandleChar(int targetArtMethod, int sp) {

        FastHookParam param = hookHandle(targetArtMethod,sp);

    if(param.result != null && param.result instanceof Character) {

            return ((Character) param.result).charValue();

        }    

    return 0;

}

private static short hookHandleShort(int targetArtMethod, int sp) {

        FastHookParam param = hookHandle(targetArtMethod,sp);

    if(param.result != null && param.result instanceof Short) {

            return ((Short) param.result).shortValue();

        }    

    return 0;

}

private static int hookHandleInt(int targetArtMethod, int sp) {

        FastHookParam param = hookHandle(targetArtMethod,sp);

    if(param.result != null && param.result instanceof Integer) {

            return ((Integer) param.result).intValue();

        }

    return 0;

}

private static long hookHandleLong(int targetArtMethod, int sp) {

        FastHookParam param = hookHandle(targetArtMethod,sp);

    if(param.result != null && param.result instanceof Long) {

            return ((Long) param.result).longValue();

        }

    return 0;

}

private static float hookHandleFloat(int targetArtMethod, int sp) {

        FastHookParam param = hookHandle(targetArtMethod,sp);

    if(param.result != null && param.result instanceof Float) {

            return ((Float) param.result).floatValue();

        }

    return 0;

}

private static double hookHandleDouble(int targetArtMethod, int sp) {

        FastHookParam param = hookHandle(targetArtMethod,sp);

    if(param.result != null && param.result instanceof Double) {

            return ((Double) param.result).doubleValue();

        }

    return 0;

}

private static void hookHandleVoid(int targetArtMethod, int sp) {

        hookHandle(targetArtMethod,sp);

        return;

}

64位指针长度为8字节,将以long类型传入,一种返回类型对应一个Hook方法

private static Object hookHandleObject(long targetArtMethod, long sp) {

    FastHookParam param = hookHandle(targetArtMethod,sp);

    return param.result;

}

private static boolean hookHandleBoolean(long targetArtMethod, long sp) {

     FastHookParam param = hookHandle(targetArtMethod,sp);

    if(param.result != null && param.result instanceof Boolean) {

            return ((Boolean) param.result).booleanValue();

        }

    return false;

}

private static byte hookHandleByte(long targetArtMethod, long sp) {

    FastHookParam param = hookHandle(targetArtMethod,sp);

    if(param.result != null && param.result instanceof Byte) {

            return ((Byte) param.result).byteValue();

        }

    return 0;

}

private static char hookHandleChar(long targetArtMethod, long sp) {

        FastHookParam param = hookHandle(targetArtMethod,sp);

    if(param.result != null && param.result instanceof Character) {

            return ((Character) param.result).charValue();

        }

    return 0;

}

private static short hookHandleShort(long targetArtMethod, long sp) {

        FastHookParam param = hookHandle(targetArtMethod,sp);

    if(param.result != null && param.result instanceof Short) {

            return ((Short) param.result).shortValue();

        }

    return 0;

}

private static int hookHandleInt(long targetArtMethod, long sp) {

        FastHookParam param = hookHandle(targetArtMethod,sp);

    if(param.result != null && param.result instanceof Integer) {

            return ((Integer) param.result).intValue();

        }

    return 0;

}

private static long hookHandleLong(long targetArtMethod, long sp) {

        FastHookParam param = hookHandle(targetArtMethod,sp);

    if(param.result != null && param.result instanceof Long) {

            return ((Long) param.result).longValue();

        }

    return 0;

}

private static float hookHandleFloat(long targetArtMethod, long sp) {

        FastHookParam param = hookHandle(targetArtMethod,sp);

    if(param.result != null && param.result instanceof Float) {

            return ((Float) param.result).floatValue();

        }

    return 0;

}

private static double hookHandleDouble(long targetArtMethod, long sp) {

        FastHookParam param = hookHandle(targetArtMethod,sp);

    if(param.result != null && param.result instanceof Double) {

            return ((Double) param.result).doubleValue();

        }

    return 0;

}

private static void hookHandleVoid(long targetArtMethod, long sp) {

        hookHandle(targetArtMethod,sp);

        return;

}

2.2 参数解析

ART类型

类型 字节
boolean 4
byte 4
char 4
short 4
int 4
long 8
float 4
double 8
reference 4

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功