前言
阅读art源码,思考dex不落地&加密加载的实现,并含有oat过程
目标写出一个通用的android hook库,开发在AS下进行,方便运行和调试
先为了看懂:https://github.com/xiaobaiyey/dexload
钩子(hook)与注入(inject):
hook目的是修改执行逻辑,我直接理解为类似AOP的思想,不过这个更注重实现。
注入目的是非己内容加入自己代码,分为静态与动态,前者运行前修改可执行文件,后者通过ptrace等。
实现部分交集互用,有时不区分。一般hook目标需要注入为前提。
之前写过一篇注入的,但没有实现完整:https://xn--74q78i15hxv3arigm4e.cn/2018/05/26/android-hook/
猜测失败原因是Android 7.0之后对于非公开API的调用限制:
开发只要保证:连接不在apk中的库时只能连接公开的NDK,自己使用的so一定要放到apk中打包。
AOSP 7.0以后关于NDK限制机制的核心代码是在 /bionic/linker/linker.cpp,自己环境下可以修改源码来方便注入,其它环境下可以先注入处理掉检测部分,再注入自己的so。
Java Hook
Static Field Hook:静态成员hook
Method Hook:函数hook
Native So Hook
GOT Hook:全局偏移表hook
SYM Hook:符号表hook
Inline Hook:函数内联hook
本篇分析native的hook,下一篇java下针对art hook。
面向对象的核心思想是数据抽象、继承、动态绑定。
数据抽象:接口与实现分离
继承:定义相似的类型与关系建模
动态绑定:忽略类型区别、统一使用对象
c++中将要由子适应自己而改变的函数记为虚函数,子不应该改变的函数则为普通函数。
派生类列表指明从哪些类继承而来。形式: 冒号+访问说明符+类名 逗号分隔
虚函数必须定义,派生类不是必须定义父的全部虚函数,没定义的会名字找到父的实现。后加override表示编译器检查,必须这个成员改写了基类虚函数。
基类的引用指针可以绑定到派生类,反之不可,当使用基类的引用或指针调用虚函数时发生动态绑定,实际调用的函数由运行时对象决定。不加虚的由指针类型静态决定。不用指针的是拷贝赋值函数调用,会砍掉子的部分。
一个类控制自己可被访问的部分,继承只是在黑盒上再进行黑盒封装。不能控制父的私有部分。
重载运算符是有特殊名称的函数,有返回类型、参数列表、函数体:关键字operator+要定义的符号。参数与运算符作用的运算对象数量一样多,除了重载调用运算符,不能有默认实参。如果运算符函数是成员函数,则第一个运算对象绑定到隐式的this上。
运算符函数,或者是类的成员,或者至少含有一个类类型的参数。意味着不能更改内置类型的运算符。
既是一元又是二元的都能重载,根据参数数量自动判断。
运算符的优先级与结合律不变。
|
|
示例:
重载应该与内置意义一致:
成员还是非成员:
如s+”” 若是成员+改成 “”+s则不正确。因为是先定+的意义,再转化类型,这里+的意义没有找到合适的函数。
当对象为const时,内部成员的成员也不可修改,直接不可,用成员函数的话会要求为const函数,而const的函数中a.f时a也是const的,因此要求f为const。可见
对象是const的,其成员均带const属性,这个属性递归传递!!!
非动态的内存管理:由位置决定生存期,编译器自动释放
动态内存管理:自定义生存期,手动释放。
c++的动态内存管理运算符:
new,在堆中分配对象空间并返回指针,可以选择进行初始化。
delete,接受动态对象的指针,销毁对象,释放内存。
在memory头文件,标准库提供了俩种智能指针帮助管理动态对象,它依据指针生存期自动释放其指向的对象。shared_ptr共享对象,unique_ptr独占对象。
杂记:
顺序容器:以位置保存元素。关联容器:以关键字保存元素
关联容器分为如下:
按map|set、有序|无序、不重复|重复
map、multimap定义在map。set与multiset定义在set。无序定义在unordered_map与unordered_set中。
都是模板定义。
简单使用:
c++对象构造:
用 A()可以调用构造返回匿名的对象。对类直接使用()为调用构造
算法查表可以参考:
https://blog.csdn.net/strint/article/details/45308001