NativeActivity开发APP原理

11 篇文章 0 订阅
6 篇文章 0 订阅

原理

我们可以用Java开发app,或者结合使用Java和C|C++开发app,NativeActivity则为单独使用C|C++开发app提供支持。

从开发者的角度看,我们是在单独用C++开发app,但从底层看还是离不开Java。

在android源码中,已经使用java开发好了一个中间类,我们使用C++开发的Native库之所以能运行,就是因为被这个中间类使用JNI的方式调用了。

这个中间类就是NativeActivity类。

NativeActivity类

NativeActivity本质是一个java类,位于android源码的android-sdk\sources\android-22\android\app\NativeActivity.java文件中。继承自Activity类,是android自带的诸多activity类中的一种。

所有使用NativeActivity开发的app,它的AndroidMainfest.xml中,activity标记的android:name属性值都为"android.app.NativeActivity",表明这个app的activity对应的类就是android源码提供的NativeActivity类:

<activity android:name="android.app.NativeActivity" ... ...>
           ... ...
</activity>

而这个NativeActivity类的核心功能,就是在特定事件发生时,调用我们使用C++开发的Native库里的回调函数。

比如在NativeActivity.onStart函数中,调用C++开发的Native库的onStartNative函数:

protected void onStart() {
        super.onStart();
        onStartNative(mNativeHandle);
}

所以我们用C++开发的Native库,需要导出这些Native函数,app的activity才能正确运行。

开发

这就牵涉到我们使用C++开发app的两种方式:

  1. native_activity.h

  2. android_native_app_glue.h

native_activity.h

该文件位于NDK的\toolchains\llvm\prebuilt\windows-x86_64\sysroot\usr\include\android目录下。

其中定义了一个ANativeActivity类,这个类中又包含一个ANativeActivityCallbacks结构的指针:

typedef struct ANativeActivity {
    struct ANativeActivityCallbacks* callbacks;
    ... ...
}

这个ANativeActivityCallbacks结构里面就是Native库需要导出的所有函数:

typedef struct ANativeActivityCallbacks {
    void (*onStart)(ANativeActivity* activity);
    void (*onResume)(ANativeActivity* activity);
    void* (*onSaveInstanceState)(ANativeActivity* activity, size_t* outSize);
    void (*onPause)(ANativeActivity* activity);
    void (*onStop)(ANativeActivity* activity);
    void (*onDestroy)(ANativeActivity* activity);
    void (*onWindowFocusChanged)(ANativeActivity* activity, int hasFocus);
    void (*onNativeWindowCreated)(ANativeActivity* activity, ANativeWindow* window);
    void (*onNativeWindowResized)(ANativeActivity* activity, ANativeWindow* window);
    void (*onNativeWindowRedrawNeeded)(ANativeActivity* activity, ANativeWindow* window);
    void (*onNativeWindowDestroyed)(ANativeActivity* activity, ANativeWindow* window);
    void (*onInputQueueCreated)(ANativeActivity* activity, AInputQueue* queue);
    void (*onInputQueueDestroyed)(ANativeActivity* activity, AInputQueue* queue);
    void (*onContentRectChanged)(ANativeActivity* activity, const ARect* rect);
    void (*onConfigurationChanged)(ANativeActivity* activity);
    void (*onLowMemory)(ANativeActivity* activity);
} ANativeActivityCallbacks;

使用native_activity.h开发app的核心工作,就是要实现ANativeActivityCallbacks的各个接口函数,native_activity.h本身是不包含这些函数体的实现的。

android_native_app_glue.h

android_native_app_glue.h则是对native_activity.h的封装。

该文件位于NDK的\sources\android\native_app_glue目录下。

它定义了一个android_app类,在其中包含ANativeActivity类的指针成员:

struct android_app {
    ... ...
    ANativeActivity* activity;
    ... ...
}

最重要的,android_app类给所有需要导出的Native函数都提供了默认的实现代码:

void ANativeActivity_onCreate(ANativeActivity* activity, void* savedState, size_t savedStateSize) {
    LOGV("Creating: %p", activity);
    activity->callbacks->onConfigurationChanged = onConfigurationChanged;
    activity->callbacks->onContentRectChanged = onContentRectChanged;
    activity->callbacks->onDestroy = onDestroy;
    activity->callbacks->onInputQueueCreated = onInputQueueCreated;
    activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed;
    activity->callbacks->onLowMemory = onLowMemory;
    activity->callbacks->onNativeWindowCreated = onNativeWindowCreated;
    activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed;
    activity->callbacks->onNativeWindowRedrawNeeded = onNativeWindowRedrawNeeded;
    activity->callbacks->onNativeWindowResized = onNativeWindowResized;
    activity->callbacks->onPause = onPause;
    activity->callbacks->onResume = onResume;
    activity->callbacks->onSaveInstanceState = onSaveInstanceState;
    activity->callbacks->onStart = onStart;
    activity->callbacks->onStop = onStop;
    activity->callbacks->onWindowFocusChanged = onWindowFocusChanged;
    activity->instance = android_app_create(activity, savedState, savedStateSize);
}

这使得开发人员不需要自己去实现所有Native库需要导出的回调函数,只实现需要加入自定义功能的回调函数即可。

而且ANativeActivity_onCreate函数最后调用的android_app_create函数会创建一个线程:

static struct android_app* android_app_create(ANativeActivity* activity, void* savedState, size_t savedStateSize) {
    ... ...
    pthread_create(&android_app->thread, &attr, android_app_entry, android_app);
    ... ...
}

这个线程的线程函数android_app_entry会进一步调用一个名字为android_main的函数:

static void* android_app_entry(void* param) {
    ... ...
    android_main(android_app);
    ... ...
}

这个android_main函数来自外部库,需要由我们的C++代码实现:

extern void android_main(struct android_app* app);
 
 

这里,这个android_main就是我们使用C++开发app时的主函数。我们在这个android_main()函数里面的任务就是进行消息循环,做各种任务。

逆向分析

所以,当我们逆向分析一个NativeActivity开发的app时,发现Native库里导出了android_main函数,表明这是使用android_native_app_glue.h开发的。基本就可以确定android_main就是Native库的主函数,从这里入手分析即可。(如CTF题目 easy-dex)

如果在Native库里没有找到android_main函数,就表明这个NativeActivity是使用native_activity.h开发的,这时就会看到导出了ANativeActivityCallbacks结构里的诸多回调函数,这些回调函数对应app运行过程中的不同事件,我们就需要在这些回调函数中找逆向分析的入手点。

———————————————————————————————————————————

欢迎关注我的微博:大雄_RE。专注软件逆向,分享最新的好文章、好工具,追踪行业大佬的研究成果。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值