Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

使用相同classloader的情况下,7.0以上,被hook方法多次调用后,hook方法调用备份方法时,没有调用原方法,错误调用了备份方法 #28

Closed
svengong opened this issue Sep 5, 2017 · 9 comments

Comments

@svengong
Copy link

svengong commented Sep 5, 2017

因为项目的需求,希望将方案放到一个sdk里来使用。
首先尝试了7.0。
开始是成功的。后来发现当一个被hook的方法反复调用多次后,无法调用原函数了。即多次调用后出现了下面的日志:
ClassWithVirtualMethod.tac() should not be here
看了作者的文章,初步判断这种随机的问题原因为hotness的变化。经过一系列调试,最后通过查看内存发现的确是hook函数的hotness发生了变化,相应的enter_point也发生了变化,而backupMethod的ArtMethod结构体并没有任何变化。
解决办法就是修改genTrampoline1的指令,先重置hookMethod的hotness。aarch64的模式下,用trampoline2的前两个命令替换掉了trampoline1的第一个命令:
0x80, 0x00, 0x00, 0x58, 0x1f, 0x24, 0x00, 0x79,
修改一系列offset后,结果喜人,三星S8,Android7.0 完全ok;
最后,问题来了:
1.为什么是hookMethod的hottness发生了变化,导致了hookMethod调用backupMethod没有调到原函数?开始我以为是backupMethod的hotness发生了变化导致该问题;
2.虽然修改了arrch64模式下的该问题,但无法判断相应的隐患,请作者给与一些思路指导;

@garzon
Copy link

garzon commented Sep 5, 2017

不知道为什么,我android 6.0.1 armv7成功hook后也调用不了原方法,即使是第一次调用

@svengong
Copy link
Author

svengong commented Sep 5, 2017

你6.0.1armv7调用不了原方法 是作者的原工程么 还是有修改

@garzon
Copy link

garzon commented Sep 5, 2017

除了我是在app内hook而不是用DexClassLoader,代码没改过
另外示例的几个函数还hook不上...不知道为什么,可能是同一个ClassLoader的关系?按照另外一个issue,用debug编译也不行。虽然我上面提到的手写的那个hook成功了

@svengong
Copy link
Author

svengong commented Sep 6, 2017

哦,我6.0的机器app内也可以啊,不过我只试了aarch64的,其他我试一下再看

@rk700
Copy link
Member

rk700 commented Sep 6, 2017

@svengong 把hook代码与应用放在一起,在Android N上由于混合编译的原因会存在问题。

https://rk700.github.io/2017/06/30/hook-on-android-n/#%E6%B8%85%E7%A9%BAhotness_count

如果通过DexClassLoader运行时动态加载,那么hook代码会编译为机器指令,此时hookMethod是编译执行,hotness不变;但如果把hook代码放在app中,那么无法保证hookMethod是解释执行还是编译执行,如果是解释执行那么hotness就会随着不断调用而增加

@svengong
Copy link
Author

svengong commented Sep 6, 2017

嗯,作者的文章我看了,意思明白。不过为什么是hookMethod的hotness导致了调用origin没有调用到原函数,而不是origin的hotness变化导致的

@rk700
Copy link
Member

rk700 commented Sep 7, 2017

具体原因需要去调试看实际代码,猜测是hotness增加使得hookMethod被JIT编译时进行了某些优化

@rk700
Copy link
Member

rk700 commented Sep 7, 2017

#29 统一跟踪DexClassLoader的问题

@rk700 rk700 closed this as completed Sep 7, 2017
@cheasonxie
Copy link

@svengong 你好,我也遇到这个问题了,能把你的修改post出来看下吗,还有如果是arm或者x86的该怎么解决,谢谢!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants