jnitrace engine
1.0.0
เครื่องยนต์ที่ใช้โดย Jnitrace เพื่อสกัดกั้นการโทร JNI API
jnitrace-engine เป็นโครงการที่ Jnitrace ใช้เพื่อสกัดกั้นและติดตามการโทร JNI API มันได้รับการเปิดเผยว่าเป็นโครงการแยกต่างหากเพื่อให้นักพัฒนาโมดูล FRIDA ใช้เอ็นจิ้นเดียวกันเพื่อสกัดกั้นและแก้ไขการโทร JNI API โดยแอปพลิเคชัน Android
วิธีที่ง่ายที่สุดในการทำงานกับ jnitrace-engine คือการใช้ NPM:
npm install jnitrace-engine
jnitrace-engine พยายามสะท้อน FRIDA API ให้ได้มากที่สุด JNIInterceptor จัดเตรียม API เพื่อแนบการโทร JNI API ในลักษณะที่คล้ายกันมากกับ Frida Interceptor แนวคิดคือการใช้ห้องสมุดที่ใช้งานง่ายสำหรับผู้ที่คุ้นเคยกับ Frida แล้ว ตัวอย่างด้านล่างคือ JavaScript แต่โมดูลยังรองรับ TypeScript
import { JNIInterceptor } from "jnitrace-engine" ;
// Attach to the JNI FindClass method
JNIInterceptor . attach ( "FindClass" , {
onEnter ( args ) {
// called whenever the FindClass is about to be called
console . log ( "FindClass method called" ) ;
this . className = Memory . readCString ( args [ 1 ] ) ;
} ,
onLeave ( retval ) {
// called whenever the FindClass method has finished executing
console . log ( "tLoading Class:" , this . className ) ;
console . log ( "tClass ID:" , retval . get ( ) ) ;
}
} ) ; import { JNIInterceptor } from "jnitrace-engine" ;
import { JNILibraryWatcher } from "jnitrace-engine" ;
import { JNINativeReturnValue } from "jnitrace-engine" ;
import { ConfigBuilder } from "jnitrace-engine" ;
// configure the jnitrace-engine to limit what libraries to traces
const builder : ConfigBuilder = new ConfigBuilder ( ) ;
builder . libraries = [ "libnative-lib.so" ] ; // set a list of libraries to track
builder . backtrace = "fuzzy" ; // choose the backtracer type to use [accurate/fuzzy/none]
builder . includeExports = [ "Java_com_nativetest_MainActivity_stringFromJNI" ] ; // provide a list of library exports to track
builder . excludeExports = [ ] ; // provide a list of library exports to ignore
builder . env = true ; // set whether to trace the JNIEnv struct or ignore all of it
builder . vm = false ; // set whether to trace the JavaVM struct or ignore all of it
const config = builder . build ( ) ; //initialise the config - this makes it available to the engine
// An additional callback that can be used for listening to new libraries being loaded by an application
// Note this callback will be called for all libraries, not just the ones in the config
// libraries list
JNILibraryWatcher . setCallback ( {
onLoaded ( path : string ) {
console . log ( "Library Loaded " + path ) ;
console . log ( "Currently Traced Libraries" , JSON . stringify ( config . libraries ) ) ;
}
} ) ;
const findClassIntercept = JNIInterceptor . attach ( "FindClass" , {
onEnter ( args : NativeArgumentValue [ ] ) {
console . log ( "Find Class called" ) ;
args [ 1 ] = NULL ; // Change the arguments to the FindClass function
console . log ( "ThreadId" , this . threadId ) ;
console . log ( "Address of FindClass method" , this . jniAddress ) ;
this . backtrace . forEach ( ( element : NativePointer ) => {
console . log ( "backtrace" , element ) ;
} ) ;
} ,
onLeave ( retval : JNINativeReturnValue ) {
// Change the retval to be returned to the caller of FindClass
retval . replace ( NULL ) ;
// Detach all JNI intercepts
JNIInterceptor . detatchAll ( ) ;
}
} ) ;
JNIInterceptor . attach ( "CallDoubleMethodV" , {
onLeave ( retval : JNINativeReturnValue ) {
// Log the method params of the Java method the JNI API is calling.
// this.javaMethod will only exist if a Java method has been called.
console . log ( "Java Method Args" , JSON . stringify ( this . javaMethod . params ) ) ;
// Detach from the FindClass intercept
findClassIntercept . detach ( ) ;
}
} ) ;