Native code in Android
applications
My projects using NDK
Yumm
Low memory overhead for image decoding
Hudriks Math
cocos2d-x; cross-platform: iOS and Android
Secure Video Player
Critical DRM code; cross-platform code (iOS/Android/Linux/OS X/Windows);
high-performance
Overview
Your Java Application
Java code

/libs/armeabi/

Android Runtime
Core Libraries (Java)
JVM (Dalvik)

Libraries
OpenSL ES

...
Android NDK

•

Documentation

•

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

•

NDK framework headers

•

Build syste...
NDK frameworks
android-4 (1.6)
•

dl, zlib, math, log

•

OpenGL ES 1.x

android-14 (4.0)
android-5 (2.0)
•

OpenMAX

Open...
Compilation process
source

.c/.c++
.o
.o

objects
compiler

.o
.o
.o

shared library
linker

.so

static library
.a (arch...
Application structure
•

jni/ (source code)
•

Android.mk

•

[Application.mk]

•

module1/
•

•

Android.mk

libs/armeabi...
CPU specific
•

Application Binary Interface (ABI):
• armeabi - at least ARMv5TE
• armeabi-v7a - Thumb-2; VFP hardware FPU;...
Java Native Interface
JNI in C and C++
#include <jni.h>

C
struct JNINativeInterface {	
	 jclass
(*FindClass)(JNIEnv*, const char*);	
}	
typedef...
JNI in C and C++
C++
struct _JNIEnv {	
jclass FindClass(const char* name)	
{ return functions->FindClass(this, name); }	
}...
Mapping native functions
libnative.so

Java.class

- function_1()

- function_1()

- function_2()

- function_2()

- funct...
Mapping native functions
.java
public native static int testNative(int a, int b);

.c
jint Java_com_example_jnibasics_Nati...
Mapping native functions
jint RegisterNatives(JNIEnv *env, jclass clazz, const
JNINativeMethod *methods, jint nMethods);
t...
Mapping native functions
static JNINativeMethod sMethods[] = {	
{"testNative", "(II)I", (void*)addVals}	
};

jint JNI_OnLo...
Loading .so from Java
	
	
	
	
	
	
	

static {	
static {	
	
System.loadLibrary("Dependency");	
	
System.loadLibrary("JNIBas...
Demo
References
jobject gObject = NULL;	
!
void function(JNIEnv* jobject obj) {	
	 gObject = (*env)->NewGlobalRef(env, obj);	
}...
Calling Java methods from
native
jclass clz = (*env)->FindClass(env, “com/example/jnibasics/NativeDemo");	

!
jmethodID me...
Accessing java strings
jstring jstr;	
const char* str;	
!

str = (*env)->GetStringUTFChars(env, jstr, NULL);	
!

...	
!

(...
Further reading
•

Attaching Java threads

•

Creating new Java objects from native code

•

Distinguish between virtual a...
Using native code
Performance
•

Most applications don’t need native code!

•

Only for extensive calculations: games, rich media

•

Take a...
Cross-platform architecture
platform dependant
libraries
(network, UI, etc)

Application
(Java/UIKit)
platform independent...
Cross-platform examples

VLC
Security
1.
2.
3.
4.

Register as a developer (£60 per year)
Add device UUID to dev account
Generate Provisioning Profile
Sign APK w...
Demo

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

Always obfuscate Java code!

•

Never save passwords, use session key or hash
instead

•

Never keep encryption...
Further protection

•

Hide non-public symbols from .so files

•

Strip debug information into separate files

•

Expose onl...
Tips
•

Debugging native code is tricky
•
•

•

Linux or OSX as dev platform
Use ARM DS-5 Community Edition in Eclipse

An...
Questions?

Dmitry Matyukhin
dmitry@fancygames.net
Upcoming SlideShare
Loading in...5
×

Native code in Android applications

2,509

Published on

Published in: Technology, Education

Native code in Android applications

  1. 1. Native code in Android applications
  2. 2. My projects using NDK
  3. 3. Yumm Low memory overhead for image decoding
  4. 4. Hudriks Math cocos2d-x; cross-platform: iOS and Android
  5. 5. Secure Video Player Critical DRM code; cross-platform code (iOS/Android/Linux/OS X/Windows); high-performance
  6. 6. Overview
  7. 7. Your Java Application Java code /libs/armeabi/ Android Runtime Core Libraries (Java) JVM (Dalvik) Libraries OpenSL ES SQLite OpenGL Linux Platform Media
  8. 8. Android NDK • Documentation • Toolchain - ndk-build, gcc/clang, gdbserver, … • NDK framework headers • Build system
  9. 9. NDK frameworks android-4 (1.6) • dl, zlib, math, log • OpenGL ES 1.x android-14 (4.0) android-5 (2.0) • OpenMAX OpenGL ES 2.0 android-8 (2.2) • • JNI Graphics - java Bitmaps on low level android-9 (2.3) • EGL • OpenSL ES - audio library • Native Applications - native activity, etc android-18 (4.3) • OpenGL ES 3.0
  10. 10. Compilation process source .c/.c++ .o .o objects compiler .o .o .o shared library linker .so static library .a (archive) .so .o .o .o
  11. 11. Application structure • jni/ (source code) • Android.mk • [Application.mk] • module1/ • • Android.mk libs/armeabi/libnative.so - compiled shared library
  12. 12. 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
  13. 13. Java Native Interface
  14. 14. JNI in C and C++ #include <jni.h> C struct JNINativeInterface { jclass (*FindClass)(JNIEnv*, const char*); } typedef const struct JNINativeInterface* JNIEnv; ! JNIEnv* env; (*env)->FindClass(env, “classname”);
  15. 15. JNI in C and C++ C++ struct _JNIEnv { jclass FindClass(const char* name) { return functions->FindClass(this, name); } } ! JNIEnv* env; env->FindClass(“classname”);
  16. 16. Mapping native functions libnative.so Java.class - function_1() - function_1() - function_2() - function_2() - function_3() - function_3() - function_4() - function_4() - function_5() - function_5()
  17. 17. Mapping native functions .java public native static int testNative(int a, int b); .c jint Java_com_example_jnibasics_NativeDemo_testNative(JNIEnv *env, jclass obj, jint a, jint b) package name javah > javah com.example.jnibasics.NativeDemo
  18. 18. Mapping native functions jint 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) {…}
  19. 19. Mapping native functions static 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; ! klass = (*env)->FindClass(env, “com/example/jnibasics/NativeDemo”);   (*env)->RegisterNatives(env, klass, gMethods, 1); ! return JNI_VERSION_1_6; }
  20. 20. Loading .so from Java static { static { System.loadLibrary("Dependency"); System.loadLibrary("JNIBasics"); System.loadLibrary("JNIBasics"); } } JNIBasics Dependency
  21. 21. Demo
  22. 22. References jobject gObject = NULL; ! void function(JNIEnv* jobject obj) { gObject = (*env)->NewGlobalRef(env, obj); } ! void finish(JNIEnv* env) { (*env)->DeleteGlobalRef(env, gObject); }
  23. 23. 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);
  24. 24. Accessing java strings jstring jstr; const char* str; ! str = (*env)->GetStringUTFChars(env, jstr, NULL); ! ... ! (*env)->ReleaseStringUTFChars(env, jstr, str);
  25. 25. Further reading • Attaching Java threads • Creating new Java objects from native code • Distinguish between virtual and non virtual methods • Exception handling • Accessing Java arrays
  26. 26. Using native code
  27. 27. 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
  28. 28. Cross-platform architecture platform dependant libraries (network, UI, etc) Application (Java/UIKit) platform independent code (no JNI) external interface (JNI/Objective-C)
  29. 29. Cross-platform examples VLC
  30. 30. Security
  31. 31. 1. 2. 3. 4. Register as a developer (£60 per year) Add device UUID to dev account Generate Provisioning Profile 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: Decompiled Java: class structures assembly code readable code
  32. 32. Demo DISCLAIMER: For educational purposes only; I’m not encouraging to hack somebody else’s applications;
  33. 33. 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
  34. 34. Further protection • Hide non-public symbols from .so files • Strip debug information into separate files • Expose only high-level APIs to Java
  35. 35. 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
  36. 36. Questions? Dmitry Matyukhin dmitry@fancygames.net
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×