-
Notifications
You must be signed in to change notification settings - Fork 352
更新说明
ce83f47 更新说明
之前处理hotness_count_
禁止JIT编译,只针对目标方法,hook方法如果运行次数多,仍然可能被JIT编译。但如果hook方法中还调用了backup方法,则可能存在编译错误的情况。所以现在对hook方法也禁止JIT编译
而又发现可以通过添加kAccCompileDontBother
这个flag,来告诉系统该方法不要编译。相比之前在trampoline中每次清空hotness_count_
,这样做更为简洁,所以删除了hotness_count_
相关代码。
a929fce 更新说明
主要进行了以下修复和更改:
-
解决了Android 8.0上hook失效问题。感谢 @svengong 及其同事的发现和建议,Android 8.0上debug包会强制走解析执行,而release不会存在问题;或者将目标方法改为native属性,目前YAHFA采用了这种方式
-
调整了一些方法名称的约定。为避免理解混乱,现在hook插件中定义的方法名改为
hook()
和backup()
(可选)。hook()
仍然是要替换成的执行内容,backup()
则是原方法的备份,其只是作为一个占位,在进行hook时backup()
会被覆盖成原方法。这里多说一句,如果要调用原方法,直接执行
backup()
即可,在backup()
之前和之后的部分,自然对应于所谓的before
和after
。有些人被Xposed影响的太深,总是想着通过类似于before
和after
的方式来进行hook,殊不知那只是Xposed的封装。如果用过Cydia Substrate,自然对YAHFA的这种hook及调用原方法的模式不会感到陌生。
-
回退到了之前显式设定cached methods的方式。这是由于以下原因:
-
该issue及修复说明,必须将原方法整体复制到备份方法中,只修改备份方法的entrypoint跳转回原方法,在某些情况下会由于
ToDexPc
错乱的问题崩溃 -
上述修复通过
malloc()
的方式创建新的ArtMethod
,而非定义Java方法,但在垃圾回收时会有问题 -
为解决上述
malloc()
的问题,曾经添加一个Java方法来保存原方法的完整备份,但这又会显得很冗余 -
于是现在是将原方法整体复制到
backup()
中,但这样就不能在backup()
中通过trampoline2清除其hotness_count了,所以这部分操作被合并到trampoline1中 -
由于
backup()
被整体替换,其方法signature被更改,所以在hook()
中首次调用静态的backup()
时,会解析失败。为解决该问题,回退到了之前显式设定cached methods的方式,从而绕过了解析静态方法backup()
的过程
-
66397a3 更新说明
显式设定cached methods中的backup()
,在高版本系统上会出现找不到backup方法NoSuchMethodError的问题。因为cached methods是一个长度有限的数组,所以设定好的内容可能会被覆盖。
于是改变思路,不再把目标方法全部复制到backup()
的结构体中,而是采用类似hook的方式,把backup()
的entrypoint替换为trampoline,在其中设置寄存器并跳转回到原始的目标方法执行。不过原始的目标方法结构体中的entrypoint已经被替换为hook()
了,所以backup()
所使用的trampoline是把入口地址硬编码而非从ArtMethod
结构体中读取。