Context
As an exercise I am researching all methods of hiding a secret in an android mobile app binary... Yes I know that with more or less effort they can always be extracted with static analyses, run time introspection or with a MITM attack.
In my research to hide the secret, the best way I found for Android is by using JNI/NDK and until now I was not able to find a way of reverse engineer it.
NOTE: I understand the high level concept of reverse engineer but I don't have any experience of doing it.
My Attempts
$ strings -aw lib/x86/libnative-lib.so | grep -C 1 -irn 'the-secret-api-key-goes-here' -
932-[^_]
933:the-secret-api-key-goes-here
934-cannot allocate __cxa_eh_globals
So I find the API key in the binary because I know it, but I would like to be able to find it by searching by the variable it is associated with:
$ strings -aw lib/x86/libnative-lib.so | grep -C 1 -irn 'JNI_API_KEY' -
$
or
$ strings -aw lib/x86/libnative-lib.so | grep -C 1 -irn 'SECRETS_API_KEY' -
$
Both doesn't return any result... I tried to use also hexdump
and objdump
without any success!!!
I tried also radare2
and retdec
but my lack of knowledge may have not helped me in finding the API keys to.
As a last attempt I have de-compiled the binary with MobSF and searched the smali code for the JNI_API_KEY
, SECRETS_API_KEY
and the-secret-api-key-goes-here
without any success.
At this point I don't want to resort to Frida or xPosed for a run-time reverse engineer technique or a MITM attack approach...
So for now I just want to know if I can employ other binary or de-compile techniques to find the API key?
NOTE: Looking for open source tools, not commercial ones.
The Code
The code that I have used to hide the API key with JNI and NDK in the Android app is the following...
file: native-lib.cpp
#include <jni.h>
#include <string>
#include "api_key.h"
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_secrets_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
// To add the API_KEY to the mobile app when is compiled you need to:
// * copy `api_key.h.example` to `api_key.h`
// * edit the file and replace this text `place-the-api-key-here` with your desired API_KEY
std::string JNI_API_KEY = SECRETS_API_KEY;
return env->NewStringUTF(JNI_API_KEY.c_str());
}
file: api_key.h
#ifndef SECRETS_API_KEY
#define SECRETS_API_KEY "the-secret-api-key-goes-here"
#endif / SECRETS_API_KEY
file: CMakeLists.txt
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
# Creates and names a library, sets it as either STATIC
# orJNI_API_KEY SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
native-lib.cpp)
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log)
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib})