Reputation: 186
I just created my first Android application that uses JNI and NDK, the simple Hello-JNI to speak. With a unique function that returns a string. I signed APK unpacked and if I see the .so files that do not seem compiled natively. I expected a binary code. I read the name of function and string. My goal is to use the SDK to write native code to hide the strings that are not clouded by proguard. I used Android Studio 2.1.2
Build.gradle project
buildscript {
repositories {
jcenter()
}
dependencies {
//classpath 'com.android.tools.build:gradle:2.1.2'
classpath 'com.android.tools.build:gradle-experimental:0.7.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Build.Gradle app
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.danielezampieri.jniapp"
minSdkVersion.apiLevel 18
targetSdkVersion.apiLevel 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles.add(file('proguard-android.txt'))
}
}
ndk {
moduleName "jniapp"
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.0.0'
compile 'com.android.support:design:23.0.0'
}
gradle-wrapper.properties
#Mon Dec 28 10:00:20 PST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
local.properties
ndk.dir=P\:\\Android\\sdk\\ndk-bundle
sdk.dir=P\:\\Android\\sdk
Upvotes: 0
Views: 957
Reputation: 16606
if your string is defined in C/C++ like:
char *mySecretString = "some secret";
Then of course it is readable in .so
, while it is natively compiled.
Compilation is not obfuscation, but translation of code into machine code of target platform. The string is not code, but data, and binary form of ASCII string data is the very same ASCII string.
Function names don't have to be visible in .so
, unless:
.so
file includes some debug info, use release mode, and strip
as needed (I do believe the NDK in release mode strips .so files enough, but I never examined it personally, so maybe they leave some debug info even in release?).So if you want to use native library for obfuscation:
For functions: use cryptic external function names, or add another layer of local functions called trough external (visible) function names, and make sure all debug info is stripped, so local symbols are not included.
For strings: encrypt the data by some encryption, include the encrypted data in .so file, then decrypt the strings into memory before usage by your decryption routine.
Mind you, anyone disassembling your code manually will be still able to find all that stuff out, if he puts enough effort into it.
Upvotes: 1