Android 逆向函数拦截 ( 使用 cache_flush 系统函数刷新 CPU 高速缓存 | 刷新 CPU 高速缓存弊端 | 函数拦截推荐时机 )

Posted 韩曙亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 逆向函数拦截 ( 使用 cache_flush 系统函数刷新 CPU 高速缓存 | 刷新 CPU 高速缓存弊端 | 函数拦截推荐时机 )相关的知识,希望对你有一定的参考价值。





一、使用 cache_flush 系统函数刷新 CPU 高速缓存



使用 " 在实际被调用的函数中添加跳转代码实现函数拦截 " 方案 进行函数拦截 , 由于存在 CPU 的高速缓存机制 , 无法保证 100% 成功 ;

这里就需要刷新 CPU 的高速缓存 , 调用 cache_flush 系统函数 , 就会将 CPU 中高速缓存中涉及到该进程的所有数据全部清除 , 然后重新从内存中加载缓存信息 , 此时就可以将 修改后 添加了跳转函数的 被拦截函数 , 重新加载到内存中去 , 此时 CPU 就可以执行 修改后的 被拦截函数 ; 拦截生效 ;





二、使用 cache_flush 系统函数刷新 CPU 高速缓存的弊端



使用 cache_flush 系统函数刷新 CPU 高速缓存的弊端 :

① 性能损耗 : CPU 重建缓存 , 导致执行效率降低 , 可能导致卡顿 , 闪退等情况 ;

② 影响其它进程 : 多核 CPU 如果刷新 高速缓存 , 可能导致其它进程的 高速缓存 也被刷新 , 影响到其它进程执行 ;

③ 影响多线程代码逻辑 : 多个线程竞争 CPU 执行权限 , 清空了 CPU 高速缓存中 ,


多线程执行的逻辑 参考 【Java 并发编程】线程简介 ( 并发类型 | 线程状态 | CPU 数据缓存 ) 博客 , Java 线程 运行时 , 每个 Java 线程都配套一个 工作内存 , 然后工作内存从 主内存 中获取数据 , 主内存被所有工作内存共享 ;

  • 工作内存 就是 线程的 本地内存 , 其中存储的是主内存中的 变量副本 , 使用主内存的变量前 , 先将变量拷贝工作内存中 ;
  • 当在线程中 修改了工作内存中的数据 , 需要同时 将变量的修改同步到主内存中 ;

这里的 工作线程 / 本地线程 相当于 CPU 中的 L1 / L2 缓存 , 主内存 相当于 CPU 中的 L3 缓存 ;

如果把高速缓存清了 , 多线程执行肯定会存在问题 ;





三、函数拦截推荐时机



鉴于 函数拦截 需要 清空 CPU 高速缓存 有上述弊端 , 因此这里建议在 程序初始化时进行函数拦截 , 不要在程序运行过程中进行 函数拦截 ;

如果必须在程序启动后进行拦截 , 只能冒险进行 清空 CPU 高速缓存 , 但是建议一次性把所有的函数拦截都做了 , 不要频繁进行 函数拦截 + 清空 CPU 高速缓存 操作 , 次数越多 , 出问题的几率就越大 ;

以上是关于Android 逆向函数拦截 ( 使用 cache_flush 系统函数刷新 CPU 高速缓存 | 刷新 CPU 高速缓存弊端 | 函数拦截推荐时机 )的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向函数拦截实例 ( ③ 刷新 CPU 高速缓存 | ④ 处理拦截函数 | ⑤ 返回特定结果 )

Android 逆向函数拦截 ( GOT 表拦截 与 插桩拦截 | 插桩拦截简介 | 插桩拦截涉及的 ARM 和 x86 中的跳转指令 )

Android 逆向函数拦截原理 ( 通过修改 GOT 全局偏移表拦截函数 | 通过在实际被调用的函数中添加跳转代码实现函数拦截 )

Android 逆向函数拦截 ( ARM 架构下的插桩拦截 | 完整代码示例 )

Android 逆向函数拦截 ( 修改内存页属性 | x86 架构插桩拦截 )

Android 逆向函数拦截实例 ( ② 插桩操作 | 保存实际函数入口 6 字节数据 | 在插桩的函数入口写入跳转指令 | 构造拼接桩函数 )