36
Native code in Android applications

Native code in Android applications

Embed Size (px)

Citation preview

Page 1: Native code in Android applications

Native code in Android applications

Page 2: Native code in Android applications

My projects using NDK

Page 3: Native code in Android applications

YummLow memory overhead for image decoding

Page 4: Native code in Android applications

Hudriks Mathcocos2d-x; cross-platform: iOS and Android

Page 5: Native code in Android applications

Secure Video PlayerCritical DRM code; cross-platform code (iOS/Android/Linux/OS X/Windows);

high-performance

Page 6: Native code in Android applications

Overview

Page 7: Native code in Android applications

Android Runtime

Core Libraries (Java)

JVM (Dalvik)

LibrariesMediaSQLite OpenGLOpenSL ES

Linux Platform

/libs/armeabi/

Your Java Application

Java code

Page 8: Native code in Android applications

Android NDK

• Documentation

• Toolchain - ndk-build, gcc/clang, gdbserver, …

• NDK framework headers

• Build system

Page 9: Native code in Android applications

NDK frameworks• dl, zlib, math, log • OpenGL ES 1.x

android-4 (1.6)

• OpenGL ES 2.0

android-5 (2.0)

• JNI Graphics - java Bitmaps on low level

android-8 (2.2)

• EGL • OpenSL ES - audio library • Native Applications - native activity, etc

android-9 (2.3)

• OpenMAX

android-14 (4.0)

• OpenGL ES 3.0

android-18 (4.3)

Page 10: Native code in Android applications

Compilation process

compiler

source objects

.o.o.o.o.o.c/.c++ linker .so

shared library

static library

.o.o.o

.a (archive)

.so

Page 11: Native code in Android applications

Application structure

• jni/ (source code)

• Android.mk

• [Application.mk]

• module1/

• Android.mk

• libs/armeabi/libnative.so - compiled shared library

Page 12: Native code in Android applications

CPU specific

• Application Binary Interface (ABI): • armeabi - at least ARMv5TE • armeabi-v7a - Thumb-2; VFP hardware FPU; NEON • x86 • mips

• Application.mk: • APP_ABI := all • APP_ABI := armeabi armeabi-v7a

Page 13: Native code in Android applications

Java Native Interface

Page 14: Native code in Android applications

JNI in C and C++#include <jni.h>

struct JNINativeInterface { jclass (*FindClass)(JNIEnv*, const char*);}typedef const struct JNINativeInterface* JNIEnv;!JNIEnv* env;(*env)->FindClass(env, “classname”);

C

Page 15: Native code in Android applications

JNI in C and C++

struct _JNIEnv { jclass FindClass(const char* name) { return functions->FindClass(this, name); }}!JNIEnv* env;env->FindClass(“classname”);

C++

Page 16: Native code in Android applications

Mapping native functions

libnative.so- function_1()

- function_2()

- function_3()

- function_4()

- function_5()

Java.class- function_1()

- function_2()

- function_3()

- function_4()

- function_5()

Page 17: Native code in Android applications

Mapping native functions

public native static int testNative(int a, int b);

.java

jint Java_com_example_jnibasics_NativeDemo_testNative(JNIEnv *env, jclass obj, jint a, jint b)

.c

package name

> javah com.example.jnibasics.NativeDemo

javah

Page 18: Native code in Android applications

Mapping native functionsjint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods, jint nMethods);

typedef struct { char *name; char *signature; void *fnPtr; } JNINativeMethod;

jint addVals(JNIEnv *env, jclass obj, jint a, jint b) {…}

Page 19: Native code in Android applications

Mapping native functionsstatic JNINativeMethod sMethods[] = { {"testNative", "(II)I", (void*)addVals}};

jint JNI_OnLoad(JavaVM* vm, void* reserved) {

JNIEnv *env = NULL; jclass klass; if((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_6) != JNI_OK) return -1;! ! return JNI_VERSION_1_6;}

klass = (*env)->FindClass(env, “com/example/jnibasics/NativeDemo”);  (*env)->RegisterNatives(env, klass, gMethods, 1);

Page 20: Native code in Android applications

Loading .so from Java

static { System.loadLibrary("JNIBasics"); }

JNIBasics Dependency

static { System.loadLibrary("Dependency"); System.loadLibrary("JNIBasics"); }

Page 21: Native code in Android applications

Demo

Page 22: Native code in Android applications

References

jobject gObject = NULL;!void function(JNIEnv* jobject obj) { gObject = (*env)->NewGlobalRef(env, obj);}!void finish(JNIEnv* env) { (*env)->DeleteGlobalRef(env, gObject);}

Page 23: Native code in Android applications

Calling Java methods from native

jclass clz = (*env)->FindClass(env, “com/example/jnibasics/NativeDemo");!jmethodID method = (*env)->GetMethodID(env, clz, "methodName", “(II)Ljava/lang/String;");!jstring result = (*env)->CallObjectMethod(env, obj, method, 5, 6);

Page 24: Native code in Android applications

Accessing java strings

jstring jstr;const char* str;!str = (*env)->GetStringUTFChars(env, jstr, NULL);!...!(*env)->ReleaseStringUTFChars(env, jstr, str);

Page 25: Native code in Android applications

Further reading

• Attaching Java threads

• Creating new Java objects from native code

• Distinguish between virtual and non virtual methods

• Exception handling

• Accessing Java arrays

Page 26: Native code in Android applications

Using native code

Page 27: Native code in Android applications

Performance

• Most applications don’t need native code!

• Only for extensive calculations: games, rich media

• Take advantage of NEON CPU instructions

• Avoiding Java Garbage Collection

Page 28: Native code in Android applications

Cross-platform architecture

platform independent code

(no JNI)

platform dependant libraries

(network, UI, etc)

external interface (JNI/Objective-C)

Application (Java/UIKit)

Page 29: Native code in Android applications

Cross-platform examples

VLC

Page 30: Native code in Android applications

Security

Page 31: Native code in Android applications

1. Register as a developer (£60 per year) 2. Add device UUID to dev account 3. Generate Provisioning Profile 4. Sign APK with developer’s certificate !or Submit to Apple Store or Jailbreak device

Binary is encrypted Decryption is on OS level

Self-signed APK or not-signed at all

Decompiled Objective C: class structures assembly code

Decompiled Java: readable code

Page 32: Native code in Android applications

Demo

DISCLAIMER: For educational purposes only; I’m not encouraging to hack somebody else’s applications;

Page 33: Native code in Android applications

Summary

• Always obfuscate Java code!

• Never save passwords, use session key or hash instead

• Never keep encryption keys in clear data in memory

• Keep all critical code in native

Page 34: Native code in Android applications

Further protection

• Hide non-public symbols from .so files

• Strip debug information into separate files

• Expose only high-level APIs to Java

Page 35: Native code in Android applications

Tips

• Debugging native code is tricky

• Linux or OSX as dev platform

• Use ARM DS-5 Community Edition in Eclipse

• Android fragmentation

• separate .so files for different version

Page 36: Native code in Android applications

Questions?

Dmitry Matyukhin [email protected]