安卓内联汇编开发 密级: 【C-1】 | 时间:2024-02-20 | 目录:编程开发 | 编辑本文 文章距今已发表三个月,请自行判断文中技术方法、代码的有效性:) ## C++ 实现uname ```c++ extern "C" JNIEXPORT jstring JNICALL Java_com_example_a2023110803_common_NativeFunctions_libcUname(JNIEnv *env, jclass clazz) { // TODO: implement libcUname() struct utsname buffer; errno = 0; if (uname(&buffer) < 0) { LOGD("uname"); } jstring param1 = env->NewStringUTF(buffer.release); return param1; } ``` 通过调用uname函数,将返回值记录在buffer中。 此时攻击者通过hook常见的系统调用函数可以直接修改结果与返回值,不够安全。 ## 内联汇编获取Uname结果 ``` c++ extern "C" JNIEXPORT jstring JNICALL Java_com_example_a2023110803_common_NativeFunctions_inlineUname(JNIEnv *env, jclass clazz) { // TODO: implement inlineUname() struct utsname buffer; raw_syscall(__NR_uname,&buffer); return env->NewStringUTF(buffer.release); } ``` raw_syscall定义于Syscall.S,这段汇编代码是一个用于执行系统调用的函数 raw_syscall。它使用了ARM64架构的指令。 ``` .text .global raw_syscall .type raw_syscall,@function raw_syscall: MOV X8, X0 MOV X0, X1 SVC 0 RET ``` 需要额外添加一些配置,首先在这个函数调用位置添加一个函数声明: ``` extern "C" long raw_syscall(int i,utsname *pUtsname); ``` 引用 ``` #include ``` asm/unistd.h 是一个头文件,它定义了与系统调用相关的常量和函数原型。它通常用于在汇编语言中使用系统调用。通过包含 asm/unistd.h 头文件,汇编程序可以使用系统调用的常量和函数原型,从而能够直接调用系统调用,执行底层的操作,如文件操作、进程管理、网络通信等。 cmakes配置: ![](https://p0.meituan.net/xianfu/7b62ada628b5ef7628c66ede8edd077d29907.png%40watermark=1&&object=L3dkY2Zsb3cvN2RiN2M4NTFjYmVjZDg4MTM1OTZjMTYzOWE2MzQ4MDM0MjY0LnBuZw==&p=8&t=90&x=10&y=10) ![](https://p0.meituan.net/xianfu/5f62f59e380fb282261e7e210c01a6385962.png%40watermark=1&&object=L3dkY2Zsb3cvN2RiN2M4NTFjYmVjZDg4MTM1OTZjMTYzOWE2MzQ4MDM0MjY0LnBuZw==&p=8&t=90&x=10&y=10) 通过使用b哥的工具,可以hook svc系统调用 ``` python multi_frida_seccomp.py com.example.a2023110803 ``` ![](https://p0.meituan.net/xianfu/7f3b98a91658e6cf31ccf65f3e57993f132558.png%40watermark=1&&object=L3dkY2Zsb3cvN2RiN2M4NTFjYmVjZDg4MTM1OTZjMTYzOWE2MzQ4MDM0MjY0LnBuZw==&p=8&t=90&x=10&y=10) ## Frida Work 忘掉上文,假定自己找到了一个svc调用的口子。ida反编译 ![](https://p1.meituan.net/xianfu/6f5a38e8c9d97ad74f9f3faadb9a74ba101886.png%40watermark=1&&object=L3dkY2Zsb3cvN2RiN2M4NTFjYmVjZDg4MTM1OTZjMTYzOWE2MzQ4MDM0MjY0LnBuZw==&p=8&t=90&x=10&y=10) 看到svc调用,查看相关文档,https://chromium.googlesource.com/chromiumos/docs/+/master/constants/syscalls.md ![](https://p1.meituan.net/xianfu/6a43c8cd4c556293a7a0c9f79a840fff41593.png%40watermark=1&&object=L3dkY2Zsb3cvN2RiN2M4NTFjYmVjZDg4MTM1OTZjMTYzOWE2MzQ4MDM0MjY0LnBuZw==&p=8&t=90&x=10&y=10) 可以看到x8寄存器是opcode,这是系统调用函数约定。通过frida hook一下此时寄存器的值。 ![](https://p1.meituan.net/xianfu/8e03d9e93f30e2161a7c9fe2a30a77b4234628.png%40watermark=1&&object=L3dkY2Zsb3cvN2RiN2M4NTFjYmVjZDg4MTM1OTZjMTYzOWE2MzQ4MDM0MjY0LnBuZw==&p=8&t=90&x=10&y=10) 发现x8是a0,对应 ![](https://p0.meituan.net/xianfu/5d6673bc157178f85f240e72e6bde55513604.png%40watermark=1&&object=L3dkY2Zsb3cvN2RiN2M4NTFjYmVjZDg4MTM1OTZjMTYzOWE2MzQ4MDM0MjY0LnBuZw==&p=8&t=90&x=10&y=10) 得知此系统调用应该有两个函数,一个opcode=0xa0,一个结构体指针,用于保存信息。查看函数的交叉引用: ![](https://p1.meituan.net/xianfu/8877da4e507bbcbd918ad6dfc9718774100644.png%40watermark=1&&object=L3dkY2Zsb3cvN2RiN2M4NTFjYmVjZDg4MTM1OTZjMTYzOWE2MzQ4MDM0MjY0LnBuZw==&p=8&t=90&x=10&y=10) ![](https://p0.meituan.net/xianfu/7897d3bafd7025e364f15ef86122a22362599.png%40watermark=1&&object=L3dkY2Zsb3cvN2RiN2M4NTFjYmVjZDg4MTM1OTZjMTYzOWE2MzQ4MDM0MjY0LnBuZw==&p=8&t=90&x=10&y=10) 发现这里把0xa0赋值给w0,x1为sp+0x60,之后才跳转到raw_syscall函数。sp 是栈指针(Stack Pointer)的缩写。栈指针是一个特殊的寄存器,用于指示当前栈的顶部位置。联系上文,所以x1是utsname结构体指针的地址。所以用frida hook即可,sp的值由函数负责栈平衡,所以不会改变。 Hook时机为0x3126CC,执行完毕raw_syscall函数后,无条件跳转,使用hexdump获取指定地址内存中的值: ![](https://p0.meituan.net/xianfu/5da04dd126449a438cdf64d15db3defd290089.png%40watermark=1&&object=L3dkY2Zsb3cvN2RiN2M4NTFjYmVjZDg4MTM1OTZjMTYzOWE2MzQ4MDM0MjY0LnBuZw==&p=8&t=90&x=10&y=10) 发现值确实获取到了,找到这个结构体的定义 ![](https://p0.meituan.net/xianfu/e7c97d2f07e0fa977790b79f978aa75a116913.png%40watermark=1&&object=L3dkY2Zsb3cvN2RiN2M4NTFjYmVjZDg4MTM1OTZjMTYzOWE2MzQ4MDM0MjY0LnBuZw==&p=8&t=90&x=10&y=10) 定义了sysname、nodename、release等信息,每个属性都占65个字节。从起始位置开始取值,65字节一组,取6组即可。或者拖出来自己分也行:) 评论列表 写评论 您的IP:18.226.180.81,临时用户名:6a8cb4f1评论已接入DepyWAF审计与流量系统,请勿频繁操作导致IP拉黑 提交评论 © 版权声明:非标注『转载』情况下本文为原创文章,版权归 Depy's docs 所有,转载请联系博主获得授权。