# Native 基础

一般来讲,在 Android 开发中,除了使用 Java 语言开发并编译为 dex 文件然后由 ART 虚拟机执行的方式外,和 web 端的 wasm 一样,移动端也纯在套用 c 代码进行开并编译执行的方式 (通过 java Native Interface 可以调用 C/C 函数)。

优点:

  • 性能
  • 安全

# NDK 开发流程

# 静态注册

直接 android Studio 新建一个 C++demo

image-20220731102519921

可以看到这里相比于普通的 java 开发,多了一个 cpp 文件,然后这里应该是返回了一个字符

image-20220731102716523

然后在 mainactivity 中,可以看到,这里实际上就是将 native 中的字符渲染到 TextViewz 组件中

打包为 APK 后,用 jadx 打开

image-20220731103653417

源码几乎和本地的没啥区别,接着用 ida 打开对应的 so 文件

image-20220731105504825

用 objection 查看

image-20220731154452579

这里指代的是对应的基地址,由于基地址每次都是变化的,所以我们需要要拿到对应的相对地址

方法地址=基地址+偏移地址方法地址=基地址+偏移地址

偏移地址直接从 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)

image-20220731224137172

# 函数地址 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

Edited on

Give me a cup of [coffee]~( ̄▽ ̄)~*

Mr2 WeChat Pay

WeChat Pay