Principle of NativeActivity APP development

Posted by phpcode on Fri, 11 Feb 2022 02:28:48 +0100

principle

We can use java to develop apps, or use Java and C|C + + to develop apps. NativeActivity provides support for developing apps using C|C + + alone.

From the perspective of developers, we are developing app s in C + + alone, but from the bottom, we still can't do without Java.

In the android source code, an intermediate class has been developed using java. The reason why the Native library developed with C + + can run is that it is called by this intermediate class using JNI.

This intermediate class is the NativeActivity class.

NativeActivity class

NativeActivity is essentially a java class, which is located in Android SDK \ sources \ android-22 \ Android \ app \ NativeActivity java file. It inherits from the activity class and is one of many activity classes that Android comes with.

For all apps developed using NativeActivity, its androidmainfest In the XML, the value of the android:name attribute of the activity tag is "android.app.NativeActivity", indicating that the class corresponding to the activity of this app is the NativeActivity class provided by the android source code:

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

The core function of this NativeActivity class is to call the callback function in the Native library developed with C + + when a specific event occurs.

For example, in nativeactivity In the onStart function, the onStartNative function of the Native library developed by C++ is called:

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

Therefore, for the Native library developed in C + +, we need to export these Native functions so that the activity of the app can run correctly.

development

This involves two ways of using C + + to develop app s:

  1. native_activity.h

  2. android_native_app_glue.h

native_activity.h

The file is located in \ toolchains \ llvm \ prebuilt \ windows x86 of NDK_ 64 \ sysRoot \ usr \ include \ Android directory.

An ANativeActivity class is defined, which contains a pointer to the ANativeActivityCallbacks structure:

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

This ANativeActivityCallbacks structure contains all the functions that the Native library needs to export:

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;

Using native_activity.h the core work of app development is to implement various interface functions of ANativeActivityCallbacks, native_activity.h itself does not contain the implementation of these function bodies.

android_native_app_glue.h

android_native_app_glue.h is for native_activity.h packaging.

The file is located in \ sources \ Android \ native of NDK_ app_ Glue directory.

It defines an android_app class, which contains pointer members of ANativeActivity class:

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

Most importantly, Android_ The app class provides default implementation code for all Native functions to be exported:

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);
}

This makes developers do not need to implement all the callback functions that need to be exported from the Native library, but only the callback functions that need to add custom functions.

And ANativeActivity_onCreate function last called android_ app_ The create function creates a thread:

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);
    ... ...
}

The thread function of this thread is android_app_entry will further call a file named android_main function:

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

This Android_ The main function comes from an external library and needs to be implemented by our C + + Code:

extern void android_main(struct android_app* app);

Here, this android_main is the main function when we use C + + to develop app s. We're on Android_ The task in the main () function is to cycle messages and do various tasks.

backward analysis

Therefore, when we reverse analyze an app developed by NativeActivity, we find that Android is exported from the Native library_ The main function indicates that this is using android_native_app_glue.h developed. You can basically determine android_main is the main function of Native library, which can be analyzed from here. (such as CTF Title easy DEX)

If Android is not found in the Native library_ The main function indicates that the NativeActivity uses Native_ activity. At this time, you will see that many callback functions in the ANativeActivityCallbacks structure are exported. These callback functions correspond to different events in the running process of the app. We need to find the starting point of reverse analysis in these callback functions.

---------------------—

Welcome to my microblog: Daxiong_ RE. Focus on software reverse, share the latest good articles and tools, and track the research results of industry leaders.

Topics: Android