# Native 基础
一般来讲,在 Android 开发中,除了使用 Java 语言开发并编译为 dex 文件然后由 ART 虚拟机执行的方式外,和 web 端的 wasm 一样,移动端也纯在套用 c 代码进行开并编译执行的方式 (通过 java Native Interface 可以调用 C/C 函数)。
优点:
- 性能
- 安全
# NDK 开发流程
# 静态注册
直接 android Studio 新建一个 C++demo
可以看到这里相比于普通的 java 开发,多了一个 cpp 文件,然后这里应该是返回了一个字符
然后在 mainactivity 中,可以看到,这里实际上就是将 native 中的字符渲染到 TextViewz 组件中
打包为 APK 后,用 jadx 打开
源码几乎和本地的没啥区别,接着用 ida 打开对应的 so 文件
用 objection 查看
这里指代的是对应的基地址,由于基地址每次都是变化的,所以我们需要要拿到对应的相对地址
偏移地址直接从 ida 拿就好了,
# 导出函数名 hook
function hook_native () { | |
var addr = Module.getExportByName("libnativeappdemo.so", "Java_com_example_nativeappdemo_MainActivity_stringFromJNI") | |
Interceptor.attach(addr, { | |
onEnter: function (args) { | |
console.log('jnienv pointer =>', args[0]) | |
console.log('jobj pointer =>', args[1]) | |
}, | |
onLeave: function (retval) { | |
console.log('retval is =>', Java.vm.getEnv().getStringUtfChars(retval, null).readCString()) | |
console.log('---------') | |
} | |
}) | |
} | |
setImmediate(hook_native) |
# 函数地址 hook
Java.perform(function(){ | |
console.log("so start:") | |
var address = Module.findBaseAddress("libnativeappdemo.so").add(地址); | |
console.log("func address:", address) | |
Interceptor.attach(address, { | |
onEnter: function (args) { | |
console.log("params1", Memory.readCString(args[0])); | |
}, | |
onLeave: function (retval) { | |
console.log("here???", retval) | |
} | |
}) | |
) |
这里的地址可以直接用 ida 查看,对于 32 位的需要 + 1