payatu.com Open in urlscan Pro
188.114.97.10  Public Scan

URL: https://payatu.com/blog/amit/explore_android_native_modules_using_frida
Submission: On May 10 via api from US — Scanned from DE

Form analysis 1 forms found in the DOM

<form novalidate="" class="news-letter-form ng-untouched ng-pristine ng-valid"><input type="textbox" name="emailTextBox" placeholder="Your E-Mail Address" class="subscribe-email ng-untouched ng-pristine ng-valid"><button class="subscribe-button"
    disabled="">SUBSCRIBE</button></form>

Text Content

Services Products Who we are Resources Contact Us We are Hiring
⌂Home › ☷All Blogs › ✍amit ›
Exploration of Native Modules on Android with Frida
amit19-July-2021



EXPLORATION OF NATIVE MODULES ON ANDROID WITH FRIDA

In this blog, we will demonstrate the Use of Frida for instrumentation of Native
Modules in Android Application while doing android Application Pentesting. also
explain the Frida Android Apis. We will show you some examples that highlight
what Frida can do. In our Previous Blog, you are already familiar with Frida, if
you didn’t familiar with Frida please go through the previous blog. Getting
started with Frida on Android Apps


PREREQUISITES

Before starting with Exploration_of_Native_Modules_on_Android, it is assumed
that the reader has prior knowledge of Frida, and also has a basic understanding
of NDK(Native development kit). It would help to better Understanding of API
calls and build your own custom tools while exploring/enumerating Application
native modules.


INTRODUCTION

Mobile security testing of Android applications includes code reviews to
understand how the application logic and flow works and identify potential
security vulnerabilities. If the app was developed in Java, decompiling the app
means reversing the compilation process to extract the Java source code from the
binary compiled code. but If native Libraries are used in the application then
It is not possible to decompile and retrieve the source code of a compiled C/C++
native library. In such a case Frida is a very useful tool. It allows the
penetration tester to inject their code (JavaScript) inside a program.

> let’s Have A Basic Overview About Some Basic Terms of Native Library
> Implementation in Android.


WHAT IS ANDROID NDK?

The NDK (Native Development Kit) is a tool that allows you to program in C/C++
for Android devices. It’s intended to integrate with the SDK (it’s described as
a “companion tool”) and used only for performance-critical portions of a
project. The source code is compiled directly into machine code for the CPU (and
not into an intermediate language, as with Java) then developerscano get the
best performance. So, whenever you want to make some high-performance
applications for great speed or want to use some preexisting code written in
some native language then you can use C or C++

What if you want to use both Java/Kotlin and native language in your
application? This is the most used case. Is it possible to use Java code from
C++ and vice-versa? How will the Java code communicate with the native code? The
communication is done by JNI. What is this JNI?


WHAT IS JNI ?

 * JNI or Java Native Interface is the interface between your Java/Kotlin and
   the C/C++ code.
 * To be able to call native libraries from Java code, a framework named Java
   Native Interface (JNI) is used. Using this interface, C/C++ functions are
   mapped as methods and primitive data types are converted between Java and
   C/C++.
 * For this to work, special syntax is needed for JNI to recognize which method
   in which class a native function should correspond to.
 * To mark a function as native in Java, a special keyword called native is used
   to define a method.
 * Java or Kotlin Code uses JNI to communicate with the C or C++ code.

> Now we have basic understanding about the NDk,JNI , and their compilation
> process in android. Lets Proceed to the Enumeration and Hooking Part of Native
> Libraries .


FINDING NATIVE LIBRARIES

 * First of all, we must understand if the app actually uses any native
   functions, therefore we need to locate these native libraries.
 * A native library is a .so file, where “so” stands for Shared Object, which is
   essentially a compiled C file. On Android, we can have two types of native
   library: system (for example libc.so) and custom application ones (for
   example myApp.so). Custom libs for the apps in their respective app
   directories (_/data/data/package_name/lib/).
 * Or You can check the Application specific library by extracting the
   application in their repective directories .





Having identified native libraries are being used, the next step consists of
inspecting the Java class code to understand where and when these native
libraries are actually loaded by the app. This task can be done by searching for
the Java method: System.loadLibrary().




FINDING NATIVE FUNCTIONS

we need to identify the actual C functions implemented in these native
libraries. These are invoked directly within the app and are the link between C
and Java. This link is defined by the JNI (Java Native Interface), which
requires these functions to be declared within a Java class file by using the
keyword “_native_” and then wrapped inside a normal Java method.

 * Decalration of native function in Java class file



 * Actual Native functions In Native Library



> So far we have learned to find native libraries and native functions in
> android application . Lets Enumerate /Inspect native functions dynamically
> Using Frida


DYNAMIC EXPLORATION USING FRIDA


USING FRIDA-TRACE

frida-trace is a tool for dynamically Monitoring/tracing Method calls. It is
useful for debugging method calls on every event in mobile application.

CODE-SNIPPETS:

 * Tracing all Functions Calls In native Library

frida-trace -U -I "libnative-lib*" com.example.nativrproject


this command shows usage to trace any function for a given library, specified by
the “the -I”



 * Tracing JNI functions in Native Library

frida-trace -U -i “Java_*” [package_name]


This command shows usage to trace all JNI function.



TO know more about frida-trace : Usages

frida-trace --help



USING FRIDA APIS

PROCESS.ENUMERATEMODULES:

This will return an array of Module objects that have been loaded at runtime by
the spawned app process

Basically this Frida API enumerate all Native library that is loaded at runtime
of application

A Frida Module object has the following properties (similar to a Java class
variable):

 * name: representing the name of the module as a string

 * base: representing the base, initial address (in a hexadecimal
   representation) of that module currently loaded in memory

 * size: representing how big the module is in bytes

 * path: representing the full filesystem path as a string

Code-Snippet:

var process = Process.enumerateModules()

console.log(process.length)

var i =0;

for(i=0;i<process.length;i++){

console.log(JSON.stringify(process[i]))

}


 * OR you can simply check by Process.enumerateModules()

Spawn the application :-> frida -U com.example.nativrproject

Entered into the shell :> Process.enumerateModules()





PROCESS.ENUMERATEEXPORTS:

This Returns an array of objects representing Exports, these are then
represented as text with JSON.stringify().

An Export object has the following properties:

 * type: representing what the export is, it can be either a function or a
   variable

 * name: representing the name of this function/variable

 * address: representing the current memory address of this specific
   function/variable

This API Will return all exported functions,variable of given module.

Code-Snippet

 * Enumerate all functions & Variable of the Given Module

var process = Process.enumerateModules()

console.log(process.length)

var i =0;

for(i=0;i<process.length;i++){

if(process[i].path.indexOf('libnative-lib')!=-1)

{

console.log(JSON.stringify(process[i])+"\n")

var exports = process[i].enumerateExports()

for(var j =0;j<exports.length;j++){

console.log(JSON.stringify(exports[j]))

}}}




 * Enumerate all The JNI Functions In Given module

var process = Process.enumerateModules()

//console.log(process.length)

var i =0;

for(i=0;i<process.length;i++){

if(process[i].path.indexOf('libnative-lib')!=-1)

{

//console.log(JSON.stringify(process[i])+"\n")

var exports = process[i].enumerateExports()

for(var j =0;j<exports.length;j++){

//console.log(JSON.stringify(exports[j]))

if(exports[j].name.indexOf('Java_')!=-1)

{

console.log(JSON.stringify(exports[j])+"\n")

} } } }



_The script can only enumerate the modules loaded at its execution. Using the
memory base address and the size of library, monitor the memory to extract
useful values We can only enumerate modules from above Frida Apis . but cant’t
hook in specific method in android application.so For solving these issues frida
provides a powerful API Interceptor. By Using Interceptor we can intercept calls
of a Specific target function while the app is running.

INTERCEPTOR.ATTACH

Interceptor.attach(target, callbacks[, data]): intercept calls to function at
target. This is a NativePointer specifying the address of the function you would
like to intercept calls to.

target is required input of this API is a pointer indicating the current memory
address of the target function. Therefore, either we provide the actual address
, or we use Module.getExportbyName().

Frida takes care of this detail for you if you get the address from a Frida API
(for example Module.getExportByName()).

Module.getExportByName() : which will return a pointer to the function given as
input. if a specified function is not found then this will return an error.



The callbacks argument is an object containing one or more of:

 * callback function given one argument args that can be used to read or write
   arguments as an array of NativePointer objects.
 * onLeave(retval): callback function given one argument retval that is a
   NativePointer-derived object containing the raw return value.
 * retval.replace(ptr("0x1234")) to replace with a pointer

Code-Snippets

Interceptor.attach(Module.findExportByName('libnative-lib.so','Java_com_example_nativrproject_MainActivity_stringFromJNI'),{
onEnter: function(args)
{

	console.log("enterd" )

},
 onLeave: function (retval) {

 	//changing return value !!!!

            console.log("leaving")
       }

})



In above code Snippet:

 * **
   Module.findExportByName(‘libnative-lib.so’,‘Java_com_example_nativrproject_MainActivity_stringFromJNI)’**
   - Return Pointor to function
   Java_com_example_nativrproject_MainActivity_stringFromJNI
   * The callbacks for onEnter and onLeave that will be executed when and if the
     function is ever used by the running app.




BRIEF DEMONSTRATION OF NATIVE FUNCTION HOOKING!!!

Lets take an example :

 * android native code

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jint JNICALL
Java_com_example_nativrproject_MainActivity_add( JNIEnv *env, jclass abcd, jint x, jint y) {

    //return an integer
    return x *y;
}




 * JAVA Code



Application with above code print 3*4 =12 in logs. Lets hook the application jni
function and check whats paramteres are passing . we are here only to hook and
enumerate Native functions not Java functions.

Interceptor.attach(Module.findExportByName('libnative-lib.so','Java_com_example_nativrproject_MainActivity_add'),{


onEnter(args){



	 console.log('Context information:');
  

    // Save arguments for processing in onLeave.
   
    console.log("first parameter" +args[2].toInt32());
    console.log("second parameter"+ args[3].toInt32());


},

onLeave(result)
{

console.log('----------')
    // Show argument 1 (buf), saved during onEnter.
            console.log("result" + result);


            //const dstAddr = Java.vm.getEnv().newStringUtf("1234");

    const numBytes = result.toInt32();
      console.log('Result   : ' + numBytes);
  }

});






CODE-SNIPPETS FOR NATIVE CODE MANIPULATION

Interceptor.attach(Module.findExportByName('libnative-lib.so','Java_com_example_nativrproject_MainActivity_stringFromJNI'),{

onEnter: function(args)
{

	console.log("enterd" )


},
 onLeave: function (retval) {

 	//changing return value !!!!

            const dstAddr = Java.vm.getEnv().newStringUtf("1234");
            console.log(dstAddr)
            retval.replace(dstAddr);
        }

})





REFERENCES

 * https://blog.mindorks.com/getting-started-with-android-ndk-android-tutorial
 * https://medium.com/@banmarkovic/process-of-compiling-android-app-with-java-kotlin-code-27edcfcce616
 * https://frida.re/
 * https://notsosecure.com/instrumenting-native-android-functions-using-frida/
 * https://github.com/iddoeldor/frida-snippets
 * https://medium.com/swlh/exploring-native-functions-with-frida-on-android-part-1-bf93f0bfa1d3


ABOUT PAYATU

> Payatu is a Research Focused, CERT-In impaneled Cybersecurity Consulting
> company specializing in security assessments of IoT product ecosystem, Web
> application & Network with a proven track record of securing applications and
> infrastructure for customers across 20+ countries.




Get in touch with us. Click on the get started button below.

Get to know more about our process, methodology & team!
Get started today
☷All Blogs › ✍Latest Blogs
gagan.aggarwal
28-April-2022


Transition to a Safer Card Industry with PCI DSS v4.0 - A Summary Report by
Payatu

On its journey to actively updating compliance standards to tackle modern-day
cyber security threats to the Payment Card Industry, the PCI SSC (Payment Card
Industry Security Standards Council) has up

amit
27-April-2022


5 Myths About Mobile Security and Their Realities

Today smartphones have become one of the most significant aspects of our lives,
omnipresent even! In today’s era smartphones are rapidly replacing computers in
the sense that most tasks can easily b

anubhav.singh
31-March-2022


How can Hackers Analyze the Attacks on OAuth 2.0?

In this article, we will learn about the most common security vulnerabilities
encountered in applications that use the OAuth protocol. The protocol itself is
reliable but it relies heavily on the web

☷All News › ⚑Latest News
Webinar, Online 2022-04-29 00:47:52Z


Amit prajapat will be delivering a webinar on “Gaining Access to Protected
Components In Android”.

Talk, Online 2022-04-25 04:41:28Z


Yashodhan Mandke will be giving a talk on “IoT Security - Att(ack)ing I2C.”

Webinar, Online 2022-04-08 09:47:42Z


Yashodhan Mandke and Appar Thusoo delivered a talk on “Introduction to IoT
Hardware Hacking.”

Subscribe to Our Newsletter

SUBSCRIBE
or


FOLLOW OUR SOCIAL MEDIA HANDLES




Research Powered Cybersecurity Services and Training. Eliminate security threats
through our innovative and extensive security assessments.

Subscribe to our newsletter



Services

IoT Security TestingRed Team AssessmentProduct SecurityAI/ML Security AuditWeb
Security TestingMobile Security TestingDevSecOps ConsultingCode ReviewCloud
SecurityCritical Infrastructure

Products

EXPLIoTCloudFuzz

Conference

NullconHardwear.io

Resources

BlogE-BookAdvisoryMediaCase StudiesMasterClass SeriesSecurecode.wiki

About

About UsCareerNewsContact UsPayatu BanditsHardware-LabDisclosure Policy

All rights reserverved © 2021 Payatu