From 44300f35af9e09095da344ff454da472ff6417eb Mon Sep 17 00:00:00 2001 From: iddoeldor Date: Sun, 26 Aug 2018 12:19:43 +0300 Subject: [PATCH] refactoring reveal obfuscated native methods --- scripts/enumerateNativeMethods.js | 59 +++++++++++++++++-------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/scripts/enumerateNativeMethods.js b/scripts/enumerateNativeMethods.js index 218a835..58b3eb1 100644 --- a/scripts/enumerateNativeMethods.js +++ b/scripts/enumerateNativeMethods.js @@ -1,14 +1,13 @@ -var isLibARThooked = false; +// $ frida -Uf com.app --no-pause -l scripts.js +var fIntercepted = false; -function hookLibART() { - if (isLibARThooked === true) { +function revealNativeMethods() { + if (fIntercepted === true) { return; } - var symbols = Module.enumerateSymbolsSync("libart.so"); - var addrRegisterNativeMethods; var jclassAddress2NameMap = {}; - for (i = 0; i < symbols.length; i++) { - var symbol = symbols[i]; + var androidRunTimeSharedLibrary = "libart.so"; // may change between devices + Module.enumerateSymbolsSync(androidRunTimeSharedLibrary).forEach(function(symbol){ switch (symbol.name) { case "_ZN3art3JNI21RegisterNativeMethodsEP7_JNIEnvP7_jclassPK15JNINativeMethodib": /* @@ -16,22 +15,33 @@ function hookLibART() { https://demangler.com/ art::JNI::RegisterNativeMethods(_JNIEnv*, _jclass*, JNINativeMethod const*, int, bool) */ - addrRegisterNativeMethods = symbol.address; - console.log("RegisterNativeMethods is at " + addrRegisterNativeMethods); - Interceptor.attach(addrRegisterNativeMethods, { + var RegisterNativeMethodsPtr = symbol.address; + console.log("RegisterNativeMethods is at " + RegisterNativeMethodsPtr); + Interceptor.attach(RegisterNativeMethodsPtr, { onEnter: function(args) { var methodsPtr = ptr(args[2]); var methodCount = parseInt(args[3]); for (var i = 0; i < methodCount; i++) { - var namePtr = Memory.readPointer(methodsPtr.add(i * 12)); - var sigPtr = Memory.readPointer(methodsPtr.add(i * 12 + 4)); - var fnPtrPtr = Memory.readPointer(methodsPtr.add(i * 12 + 8)); + var pSize = Process.pointerSize; + /* + https://android.googlesource.com/platform/libnativehelper/+/master/include_jni/jni.h#129 + typedef struct { + const char* name; + const char* signature; + void* fnPtr; + } JNINativeMethod; + */ + var structSize = pSize * 3; // JNINativeMethod contains 3 pointers + var namePtr = Memory.readPointer(methodsPtr.add(i * structSize)); + var sigPtr = Memory.readPointer(methodsPtr.add(i * structSize + pSize)); + var fnPtrPtr = Memory.readPointer(methodsPtr.add(i * structSize + (pSize * 2))); // output schema: className#methodName(arguments)returnVal@address console.log( + // package & class, replacing forward slash with dot for convenience jclassAddress2NameMap[args[0]].replace(/\//g, '.') + - '#' + Memory.readCString(namePtr) + - Memory.readCString(sigPtr) + - '@' + fnPtrPtr + '#' + Memory.readCString(namePtr) + // method + Memory.readCString(sigPtr) + // signature (arguments & return type) + '@' + fnPtrPtr // C side address ); } }, @@ -49,16 +59,11 @@ function hookLibART() { }); break; } - } - - isLibARThooked = true; + }); + fIntercepted = true; } -Java.perform(function () { - try { - hookLibART(); - } catch (e) { - // safety first - console.error('[?]', e); - } -}); +Java.perform(revealNativeMethods); + +// TODO update +// https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05j-Testing-Resiliency-Against-Reverse-Engineering.md