-
-
[原创]记录一下YAHFA相关
-
发表于: 2021-5-14 21:18 9795
-
这里使用的手机是google Pixel XL 8.1
本文的目的是记录一下使用frida对YAHFA的原理的简单分析
首先写一个安卓demo如下
两个native方法(calledBefore/calledAfter)在native层啥也不用做 只是拿到一个反射方法
顺带附上hook代码,主要是用frida展示artmethod指针内存的变化
这里我用的是google原生系统 8.1
直接去参考源码得到 artMethod 结构体长这样:
运行起来点击textview即可得到一下日志
cpu三级流水线可知程序运行到0xf48bc018的时候
pc应该是往后的两条指令,即为0xf48bc020
这里计算一下跳板地址跳到了哪里
很明显这个位置就是 hook 函数的 entry_point_from_quick_compiledcode
继续看一下 BackUp 函数的实现
第一条指令
ldr r0, [pc, #0xc]
就是把 pc+0x2+0xc位置的值给到了r0,即等价于
ldr r0,=0xf410307c
第二条指令
stmdb sp!, {r0}
r0压栈
第三条指令
ldr r0, [pc]
等价于
ldr r0,=0xf36174d1 (这个地址就是他的默认入口)
第四条指令
ldm sp!, {pc}
将sp出到pc,也就是配置r0的值为第一个org method指针,并恢复pc为默认的函数入口 0xf36174d1
补充一点artMethod* 的4-8字节 accessflags 的变化
由 0x0008000a -> 0x0208010a
做了两步操作(标志位参考)
其他:
这是个人的一些理解哈,如果有错的地方 欢迎各位大佬指出
findViewById(R.
id
.sample_text).setOnClickListener(v
-
> {
try
{
Method doWork1
=
MainActivity.
class
.getDeclaredMethod(
"doWork1"
);
Method doWork2
=
MainActivity.
class
.getDeclaredMethod(
"doWork2"
);
Method doWork3
=
MainActivity.
class
.getDeclaredMethod(
"doWork3"
);
calledBefore(doWork1,doWork2,doWork3);
HookMain.backupAndHook(doWork1,doWork2,doWork3);
calledAfter(doWork1,doWork2,doWork3);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
});
}
private static void doWork1() {
Log.i(TAG,
"doWork1"
);
}
private static void doWork2() {
Log.i(TAG,
"doWork2"
);
}
private static void doWork3() {
Log.i(TAG,
"doWork3"
);
}
public native void calledBefore(Method doWork1, Method doWork2, Method doWork3);
public native void calledAfter(Method doWork1, Method doWork2, Method doWork3);
findViewById(R.
id
.sample_text).setOnClickListener(v
-
> {
try
{
Method doWork1
=
MainActivity.
class
.getDeclaredMethod(
"doWork1"
);
Method doWork2
=
MainActivity.
class
.getDeclaredMethod(
"doWork2"
);
Method doWork3
=
MainActivity.
class
.getDeclaredMethod(
"doWork3"
);
calledBefore(doWork1,doWork2,doWork3);
HookMain.backupAndHook(doWork1,doWork2,doWork3);
calledAfter(doWork1,doWork2,doWork3);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
});
}
private static void doWork1() {
Log.i(TAG,
"doWork1"
);
}
private static void doWork2() {
Log.i(TAG,
"doWork2"
);
}
private static void doWork3() {
Log.i(TAG,
"doWork3"
);
}
public native void calledBefore(Method doWork1, Method doWork2, Method doWork3);
public native void calledAfter(Method doWork1, Method doWork2, Method doWork3);
var getArtMethod
=
new NativeFunction(Module.findExportByName(
'libnative-lib.so'
,
'getArtMethod'
),
'pointer'
,[
'pointer'
,
'pointer'
])
Interceptor.attach(Module.findExportByName(
'libnative-lib.so'
,
'Java_com_lzy_yahfa_MainActivity_calledBefore'
),{
onEnter:function(args){
LOG(
"\n----------------------- Before -----------------------\n"
,LogColor.RED)
showLog(args[
0
],args[
2
],args[
3
],args[
4
])
},
onLeave:function(ret){
}
})
Interceptor.attach(Module.findExportByName(
'libnative-lib.so'
,
'Java_com_lzy_yahfa_MainActivity_calledAfter'
),{
onEnter:function(args){
LOG(
"\n----------------------- After -----------------------\n"
,LogColor.RED)
showLog(args[
0
],args[
2
],args[
3
],args[
4
])
},
onLeave:function(ret){
}
})
function showLog(a0,a1,a2,a3){
LOG(
" ----- ORG ----- "
,LogColor.YELLOW)
var method
=
getArtMethod(a0,a1)
seeHexA(method,p_size
*
8
)
LOG(
"entry_point_from_quick_compiled_code -> "
+
method.add(p_size
*
7
).readPointer()
+
" ---> "
+
method.add(p_size
*
7
).readPointer().readPointer())
LOG(
"\n"
)
LOG(
" ----- Hook ----- "
,LogColor.YELLOW)
var method
=
getArtMethod(a0,a2)
seeHexA(method,p_size
*
8
)
LOG(
"entry_point_from_quick_compiled_code -> "
+
method.add(p_size
*
7
).readPointer()
+
" ---> "
+
method.add(p_size
*
7
).readPointer().readPointer())
LOG(
"\n"
)
LOG(
" ----- Back ----- "
,LogColor.YELLOW)
var method
=
getArtMethod(a0,a3)
seeHexA(method,p_size
*
8
)
LOG(
"entry_point_from_quick_compiled_code -> "
+
method.add(p_size
*
7
).readPointer()
+
" ---> "
+
method.add(p_size
*
7
).readPointer().readPointer())
}
var getArtMethod
=
new NativeFunction(Module.findExportByName(
'libnative-lib.so'
,
'getArtMethod'
),
'pointer'
,[
'pointer'
,
'pointer'
])
Interceptor.attach(Module.findExportByName(
'libnative-lib.so'
,
'Java_com_lzy_yahfa_MainActivity_calledBefore'
),{
onEnter:function(args){
LOG(
"\n----------------------- Before -----------------------\n"
,LogColor.RED)
showLog(args[
0
],args[
2
],args[
3
],args[
4
])
},
onLeave:function(ret){
}
})
Interceptor.attach(Module.findExportByName(
'libnative-lib.so'
,
'Java_com_lzy_yahfa_MainActivity_calledAfter'
),{
onEnter:function(args){
LOG(
"\n----------------------- After -----------------------\n"
,LogColor.RED)
showLog(args[
0
],args[
2
],args[
3
],args[
4
])
},
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
- [原创]逆向角度看C++部分特性 22127
- [原创]__builtin_return_address()引发的思考 7032
- [原创]静态InlineHook的脚本实现 30466
- [原创]记录一下YAHFA相关 9796
- [原创]基于LIEF实现InlineHook 10039