Frida在dex2oat优化后hook的方法无效
调试发现,在hook Activity 的setRequestedOrientation(int requestedOrientation) 方法后, 有时候是正常的, 过一段时间之后就无效了.
经进一步定位分析,是发现经过dex2oat优化后, 应用使用base.odex来运行时,就变无效了.
那么到底这个方法有没有执行呢? 在AOSP源码里加了一行log:
public void setRequestedOrientation(@ActivityInfo.ScreenOrientation int requestedOrientation) {
Slog.v(TAG, "setRequestedOrientation " + requestedOrientation);
if (requestedOrientation == mLastRequestedOrientation) {
return;
}
if (mParent == null) {
ActivityClient.getInstance().setRequestedOrientation(mToken, requestedOrientation);
} else {
mParent.setRequestedOrientation(requestedOrientation);
}
mLastRequestedOrientation = requestedOrientation;
}
再重新编译刷ROM, 发现即使经过dex2oat优化,也可以hook了. 日志也有,表明肯定是执行了的.
那么问题来了,为啥加了日志之后就正常了呢? 是不是odex里有啥优化? 是不是可以对比一下有啥差异?
使用adb 命令可以触发dex2oat优化.
adb shell cmd package compile -m speed -f com.packagename
dex2oat执行完毕后,在oat的目录下,可以使用oatdump指令对比一下.
可以用filter只把一个方法dump出来,否则整个oatdump出来太大了.
#oatdump --oat-file=./base.odex --method-filter=setRequestedOrientation --class-filter=com.mobile.framework.app.ui.BaseActivity > /sdcard/setRequestedOrientation1.txt
修改Framework里的Activity.setRequestedOrientation方法,增加一行log
public void setRequestedOrientation(@ActivityInfo.ScreenOrientation int requestedOrientation) {
Slog.v(TAG, "setRequestedOrientation " + requestedOrientation);
if (requestedOrientation == mLastRequestedOrientation) {
return;
}
if (mParent == null) {
ActivityClient.getInstance().setRequestedOrientation(mToken, requestedOrientation);
} else {
mParent.setRequestedOrientation(requestedOrientation);
}
mLastRequestedOrientation = requestedOrientation;
}
通过对比增加了一行log和没有log的两个dex的相同方法发现:
应用本身的java 的dex code是一摸一样的的,

三方应用原始的Java代码如下:
public void setRequestedOrientation(int i) {
try {
super.setRequestedOrientation(i);
} catch (Throwable th) {
TraceLogger.w(this.f5279a, th);
}
}
但是生成的汇编指令差异很大.

更奇怪的是,没有日志(左边)的汇编代码量比增加了日志(右边)的还大!
那么可以猜测,是不是左边的汇编代码inline内联了我们hook的函数代码,因而没有调用我们hook的方法,导致hook失效?
加了日志之后, 生成的汇编代码没有内联android.app.Activity.setRequestedOrientation(int)方法,而是直接调用, 因此汇编代码量反而更少.
对比汇编代码,发现左边InlineInfo有10个:
InlineInfo[0] (depth=0, dex_pc=0x9, method_index=3628, is_in_bootclasspath=true, dex_file_index=5)
InlineInfo[1] (depth=1, dex_pc=0x2, method_index=3743, is_in_bootclasspath=true, dex_file_index=5)
InlineInfo[2] (depth=0, dex_pc=0xf, method_index=3628, is_in_bootclasspath=true, dex_file_index=5)
InlineInfo[3] (depth=0, dex_pc=0x15, method_index=3628, is_in_bootclasspath=true, dex_file_index=5)
InlineInfo[4] (depth=0, dex_pc=0x4, method_index=14299, is_in_bootclasspath=false, dex_file_index=2)
InlineInfo[5] (depth=0, dex_pc=0x9, method_index=3628, is_in_bootclasspath=true, dex_file_index=5)
InlineInfo[6] (depth=1, dex_pc=0x6, method_index=3743, is_in_bootclasspath=true, dex_file_index=5)
InlineInfo[7] (depth=0, dex_pc=0x0, method_index=14299, is_in_bootclasspath=false, dex_file_index=2)
InlineInfo[8] (depth=0, dex_pc=0x0, method_index=14299, is_in_bootclasspath=false, dex_file_index=2)
InlineInfo[9] (depth=1, dex_pc=0x0, method_index=28652)
右边InlineInfo只有4个
InlineInfo[0] (depth=0, dex_pc=0x4, method_index=14299, is_in_bootclasspath=false, dex_file_index=2)
InlineInfo[1] (depth=0, dex_pc=0x0, method_index=14299, is_in_bootclasspath=false, dex_file_index=2)
InlineInfo[2] (depth=0, dex_pc=0x0, method_index=14299, is_in_bootclasspath=false, dex_file_index=2)
InlineInfo[3] (depth=1, dex_pc=0x0, method_index=28652)
总结:可以确定, 执行了dex2oat优化之后, 在odex的汇编代码里内联了Framework.jar里的Activity 的setRequestedOrientation(int requestedOrientation) 方法,
因此,hook 这个方法后, odex根本没有调用这个方法.
只能寻找其他的hook点.
