Skip to content

Latest commit

 

History

History
194 lines (145 loc) · 6.35 KB

POSSIBLE_FEATURES.md

File metadata and controls

194 lines (145 loc) · 6.35 KB

#Possible Features: ##Cache Static Methods Will making the jclass property static make static methods easier?

Try testing whether JavaClassTest passes with jclass _clazz and isInitialized declared static!

If the test passes create getClass method to be used, and test for TestObject & JavaClassTest

What getStaticMethod usage would look like:

    const char* AndroidJniApp::getSignature(const char* functionName)
    {
        return "us/the/mac/android/jni/helpers/AndroidJniApp." functionName;
    }

    jobject AndroidJniApp::Instance(JNIEnv *env)
    {
        jmethodID method = JavaClass::getStaticMethod(AndroidJniApp::getSignature(__FUNCTION__))
        jobject result = env->CallStaticObjectMethod(_class, method);
        JavaExceptionUtils::checkException(env);
        return result;
    }

What getStaticMethod implmentation/usage would look like:

        jmethodID JavaClass::getStaticMethod(const char *method_name) const {
            if (!isInitialized()) {
                JavaExceptionUtils::throwExceptionOfType(JavaThreadUtils::getEnvForCurrentThread(),
                                                         kTypeIllegalStateException,
                                                         "Cannot call getMethod without class info (forgot to merge?)");
                return NULL;
            }

            const std::string key(method_name);
            MethodMap::const_iterator mapFindIter = _static_methods->find(key);
            if (mapFindIter == _static_methods->end()) {
                JavaExceptionUtils::throwExceptionOfType(JavaThreadUtils::getEnvForCurrentThread(),
                                                         kTypeIllegalArgumentException,
                                                         "Static method '%s' is not cached in class '%s'",
                                                         method_name, getCanonicalName());
                return NULL;
            }

            return mapFindIter->second;
        }

What cacheStaticSignature implmentation/usage would look like:

    cacheStaticSignature(env, "staticMethod", "()V");

    void JavaClass::cacheStaticSignature(JNIEnv *env, const char *method_name, const char *signature) {
        LOG_DEBUG("Caching static method '%s' in class '%s'", method_name, getSimpleName());
        if (!isInitialized()) {
            JavaExceptionUtils::throwExceptionOfType(env, kTypeIllegalStateException,
                                                     "Attempt to call cacheMethod without having set class info");
            return;
        }

        jmethodID method = env->GetStaticMethodID(_clazz_global.get(), method_name, signature);
        JavaExceptionUtils::checkException(env);
        if (method != NULL) {
            _static_methods_global[getCanonicalName() "." method_name] = method;
        } else {
            JavaExceptionUtils::throwExceptionOfType(env, kTypeJavaClass(NoSuchMethodError),
                                                     "Method '%s' (signature: %s) not found on class '%s'",
                                                     method_name, signature,
                                                     getCanonicalName());
        }
    }

    ...

    jobject response = AndroidJniApp::Instance(env);

##Header Obfuscation (Inserted into main c/cpp file)

What file looks like before obfuscation:

//#include "obfuscate.h"
...

    Network *network = new Network(env);
    jstring response = network->request(env, Network::HTTP_BIN);
    std::string resultString = JavaString(env, response).get();

Example generation of Obfuscation Header (obfuscate.h)

...
#define Network ghjRkl
#define network xrdtcf
#define env afh
#define response sdfgaL
#define request trlsts
#define HTTP_BIN ctfgbu
#define resultString sdtcbuh
#define JavaString xdctfin
#define get las
...

Resulting C/C++ decompilation after obfuscation

...

    ghjRkl *xrdtcf = new ghjRkl(afh);
    jstring sdfgaL = xrdtcf->trlsts(afh, ghjRkl::ctfgbu);
    std::string sdtcbuh = xdctfin(afh, sdfgaL).las();

##Android Resources Decode

Encoded Android String Resources

<resources>
    <string name="app_name">Android Jni Helpers</string>
    <string name="website_passphrase">dcfvhglasbiunpltsxrdtcfvygubhinjom</string>
</resources>

Insertion of getDecodedString(int) method into Context Classes (Application, Activity, etc.)

String decodedString = getDecodedString(R.string.website_passphrase);

##Easy Jni Replication of Android APIs

export className="org.json.JSONObject"
AndroidJniHelpers/bin/jni.bash $className

cat AndroidJniHelpers/bin/jni.files/generated/$className.jni

Example of generated Jni Helper result

org.json.JSONObject

********************************************************************************

org.json.JSONObject.jni was generated as a helper for JSONObject.java using the
bin/jni.bash script. The following code segments are C++ header and source code containing:

- getCanonicalName: The method that enables the relationship between C++ and Java.
- Java methods: org.json.JSONObject, org.json.JSONObject, length, remove, isNull, has, opt, optBoolean, optBoolean, optDouble, optDouble, optInt, optInt, optLong, optLong, optString, optString, optJSONArray, optJSONObject, keys, names, toString, quote, wrap

The source code can be copied into the respective JSONObject.h and
JSONObject.cpp files in a location of your choice. Finally, the last segment
contains an example of what these method calls would look like in your code.

********************************************************************************

#include "JniHelpers.h"

class JSONObject : public JavaClass {
  public:
    /**
    * This facsimile of the Java method java.lang.Class.getCanonicalName() is used to maintain
    * the Jni Helper's relationship to the JSONObject class defined in Java.
    */
    const char *getCanonicalName() const {
        return MAKE_CANONICAL_NAME("org/json", JSONObject);
    }
    ...

##Easy Jni Replication of Personal APIs

export className="my.personal.Object"
export filePath="file/path/to/my/personal/Object"
AndroidJniHelpers/bin/jni.bash $className $filePath

cat AndroidJniHelpers/bin/jni.files/generated/$className.jni