Frida進階-API

2020-09-05 無情劍客Burning

在前面的文章中介紹了Frida基本API的使用,在這篇文章中介紹一些更加強大的API。同時簡單介紹下HOOK 系統函數的利器frida-trace。

內存,內存還是內存。

Java對象

Java對象

Java是極其重要的API。無論想對so層亦或java層進行攔截,通常都須編Java.perform。

  • Java.available: 該函數一般用來判斷當前進程是否加載了JavaVM,Dalvik或ART虛擬機
  • Java.androidVersion: 顯示Android系統版本號
  • Java.enumerateLoadedClasses(callbacks): 枚舉當前加載的所有類信息,它有一個回調函數分別是onMatch、onComplete函數。這是一個異步的方法,有一個同步的API是Java.enumerateLoadedClassesSync。
  • Java.enumerateClassLoaders(callbacks): 枚舉Java VM中存在的類加載器,其有一個回調函數,分別是onMatch: function (loader)與onComplete: function ()。這是一個異步的方法,有一個同步的API是Java.enumerateClassLoadersSync()。
  • Java.array(type, elements): 根據指定的元素類型創建一個Java數組。

還有一些API可參考官方文檔,Java.isMainThread()、Java.registerClass(spec)、Java.deoptimizeEverything()、Java.enumerateMethods(query)等,具體用法可參考官方文檔。在12.8.20版本上沒有Java.enumerateMethods(query)這個API。

示例代碼















































function frida_Java() { Java.perform(function () { //作為判斷用 if(Java.available) { //注入的邏輯代碼 console.log(&34;,Java.androidVersion); }else{ //未能正常加載JAVA VM console.log(&34;); } //枚舉當前加載的所有類 Java.enumerateLoadedClasses({ //每一次回調此函數時其參數className就是類的信息 onMatch: function (className)          { //輸出類字符串 console.log(&34;,className); }, //枚舉完畢所有類之後的回調函數 onComplete: function (){ //輸出類字符串 console.log(&34;); } }); //枚舉當前加載的Java VM類加載器 Java.enumerateClassLoaders({ //回調函數,參數loader是類加載的信息 onMatch: function (loader)        { console.log(&34;,loader); }, //枚舉完畢所有類加載器之後的回調函數 onComplete: function ()       { console.log(&34;); } }); var values = Java.array(&39;, [ 1003, 1005, 1007 ]); var JString = Java.use(&39;); var str = JString.$new(Java.array(&39;, [ 0x48, 0x65, 0x69 ])); });} setImmediate(frida_Java,0);

部分運行結果如下:

Java.vm

Java.vm對象十分常用,比如想要拿到JNI層的JNIEnv對象,可以使用getEnv()。
















function frida_Java() { Java.perform(function () { Interceptor.attach(Module.getExportByName(null, &39;), { onEnter: function (args) { this.fileDescriptor = args[0].toInt32(); }, onLeave: function (retval) { console.log(&34;+JSON.stringify(Java.vm.getEnv())); retval.replace(1337); console.log(&34;+retval); } }); });} setImmediate(frida_Java,0);

部分運行結果:

Intercepter對象

該對象功能十分強大,函數原型是Interceptor.attach(target, callbacks):參數target是需要攔截的位置的函數地址,也就是填某個so層函數的地址即可對其攔截,target是一個NativePointer參數,用來指定你想要攔截的函數的地址,NativePointer是一個指針。需要注意的是對於Thumb函數需要對函數地址+1,callbacks則是它的回調函數,分別是以下兩個回調函數:

  • onEnter: function (args): callback function given one argument args that can be used to read or write arguments as an array of NativePointer objects.
  • onLeave: function (retval): callback function given one argument retval that is a NativePointer-derived object containing the raw return value. You may call retval.replace(1337) to replace the return value with the integer 1337, or retval.replace(ptr(&34;)) to replace with a pointer. Note that this object is recycled across onLeave calls, so do not store and use it outside your callback. Make a deep copy if you need to store the contained value, e.g.: ptr(retval.toString()).

很多時候,我們需要hook系統函數read,查看文件描述符,緩存等信息。



























function frida_Java() { Java.perform(function () { Interceptor.attach(Module.getExportByName(null, &39;), { onEnter: function (args) { console.log(&39;); console.log(&39; + JSON.stringify(this.context)); console.log(&39; + this.returnAddress); console.log(&39; + this.threadId); console.log(&39; + this.depth); console.log(&39; + this.err); // Save arguments for processing in onLeave. this.fd = args[0].toInt32(); this.buf = args[1]; this.count = args[2].toInt32(); console.log(&34;+this.fd+&34;+this.buf+&34;+this.count); }, onLeave: function (retval) { console.log(&34;+JSON.stringify(Java.vm.getEnv())); retval.replace(1337); console.log(&34;+retval); } }); });} setImmediate(frida_Java,0);

運行結果如下:

關於this比較重要的屬性在表格中列了出來:

屬性含義returnAddress返回地址,類型是NativePointercontext上下文:具有鍵pc和sp的對象,它們是分別為ia32/x64/arm指定EIP/RIP/PC和ESP/RSP/SP的NativePointer對象。其他處理器特定的鍵也可用,例如eax、rax、r0、x0等。也可以通過分配給這些鍵來更新寄存器值errno當前errno值lastError當前作業系統錯誤值threadId作業系統線程IDdepth相對於其他調用的調用深度

Interceptor.replace

相當於替換掉原本的函數,用替換時的實現替換目標處的函數。如果想要完全或部分替換現有函數的實現,則通常使用此函數。示例代碼如下,替換open函數,列印出打開文件的文件描述符和文件路徑。










var openPtr = Module.getExportByName(&39;, &39;);var open = new NativeFunction(openPtr, &39;, [&39;, &39;]);Interceptor.replace(openPtr, new NativeCallback(function (pathPtr, flags) { var path = pathPtr.readUtf8String(); log(&34;&39;&39;); var fd = open(pathPtr, flags); log(&39; + fd); return fd;}, &39;, [&39;, &39;]));

運行結果如下:

Frida-trace

官網首頁就給出了frida-trace的用法,可見其功能強大。這裡以windows記事本為例,將記事本打開的文件路徑列印出來。Frida-trace是一個動態跟蹤函數調用的工具,其強大之處在於能夠hook系統函數。

在Windwos下打開文件函數使用的是CreateFileW函數,

可以看出CreateFileW是在Kernel32.dll中導出的。

使用 frida-trace-iCreateFileWnotepad.exe開啟跟蹤,修改相應的文件如下:

使用readUtf16String是因為Windwos使用Unicode字符編碼。通過記事本打開Warcraft目錄下的ij115.dll。結果如下,打開路徑被成功列印出來。

寫在最後

Frida hook系統API是如此的簡單,不得不說,Frida is so great。

公眾號

更多Frida內容,歡迎關注我的微信公眾號。

相關焦點

  • Frida API進階
    as a stringaddress: absolute address as a NativePointerslot: memory location where the import is stored, as a NativePointer //枚舉模塊中所有中的所有導入表(Import)函數 function frida_Module_import
  • Frida API的"樂器"
    運行上面的程序(在Win10系統下),使用腳本 frida-lObjC.api: an object mapping function names to NativeFunction instances for direct access to a big portion of
  • Frida之API使用進階
    運行 frida-U-l hello.js com.lingpao.lpcf622b–debug--runtime
  • Frida API之網絡
    在Frida API進階-文件 對文件描述符、輸入輸出流進行了介紹。本篇文章集於此介紹Frida中網絡相關的API。SocketSocket.listen([options]): open a TCP or UNIX listening socket.
  • Frida常用API
    instance.getName()); // bluetoothDeviceInfo(instance); }, onComplete: function() { console.log(&34;);} }); }); });通過下面的命令運行程序frida
  • Frida腳本教程
    Hello worldHello world經典的入門程序,frida版本的來一個。frida -U -l hello.js com.android.bluetoothfrida -U -l hello.js com.android.bluetooth
  • 當Frida來「敲」門
    0x2 fridafrida是平臺原生app的Greasemonkey,說的專業一點,就是一種動態插樁工具,可以插入一些代碼到原生app的內存空間去,(動態地監視和修改其行為),這些原生平臺可以是Win、Mac、Linux、Android
  • 詳解Hook框架frida,讓你在逆向工作中效率成倍提升!
    (2) frida CLI是安裝的frida的其中一個工具,也是最常用的一個工具。2.frida serverfrida-server需要我們單獨下載,在 frida項目的github上可以直接下載對應系統已經編譯好的frida server
  • Frida全平臺使用
    pip install frida-tools網上狠毒文章說使用 pip install frida 和 pip install frida-tools 進行安裝,但是現在一條命名就夠了。如果不嫌麻煩,也可以通過源碼進行安裝。
  • 安卓安全從零到一: FRIDA hook Native基礎
    的api, 不要直接使用java的            // https://github.com/frida/frida-java-bridge/blob/062999b618451e5ac414d08d4f52bec05bd6adf6/lib/env.js            console.log('args[2]:', Java.vm.getEnv().getStringUtfChars
  • frida學習筆記3 之hook so中的方法
    hook so 常用工具SubstrateCydia-需rootfrida--需rootVA系列-非root(VA、VXP、SandVXposed)frida方式hook材料準備heibaobao.apk
  • Frida進階內存漫遊
    關於Activity的聲明周期在Frida API進階-文件有介紹。
  • Frida使用之資料庫
    下面的代碼查詢buglydb資料庫信息:function frida_Java() { Java.perform(function () { var db, smt, row, id, tm; db = SqliteDatabase.open
  • Frida之文件操作
    import frida,sysdef on_message(message, data): if message[&39;] == &39;: print(&34;.format(message[&39;])) else: print(message)passsession = frida.get_usb_device
  • Textobot-TB插件進程級API詳解&基礎篇完結
    如果是通過frida-gatget模塊注入又需要修改目標App,所以不管用哪種方式要持久化的執行JavaScript,在官方提供的接口裡面都沒有現成的。針對這個缺陷,Textobot用TB插件的模式彌補了Frida沒有持久化的問題。同時,為了方便編寫實用的TB插件,Textobot還導出了一些輔助性的C API。
  • 安卓逆向——Frida hook java層
    各位愛好安卓逆向的大佬們早上好,今天呢小弟不才在這裡拙劣的給大家講解一下咱們frida hook
  • C#進階之學習設計微服務:api認證
    2,配置網關服務Ocelot使用ocelot認證時,需要配置Ocelot.json,對相應的路由添加節點{"DownstreamPathTemplate": "/api/{url}","DownstreamScheme": "http
  • 常用api大全
    Android中文版api手冊地址:http://www.matools.com/api/androidAnt最新版api手冊地址:http://www.matools.com/api/antASM字節碼操作api手冊地址:http://www.matools.com/api/asmAxis2最新版
  • Rocket-API 版本更新,API 敏捷開發框架
    修改欄位,以便有更好的兼容性    api_info(group) 為 api_info(group_name)        api_info(comment) 為 api_info(name)        api_info_history(group) 為 api_info_history(group_name)        api_info_history(
  • 小程序的api是什麼
    其實api並不專屬於小程序,任何程式語言或程序形態都有相對應的api。而我們今天談的小程序api,是微信小程序團隊為了方便開發人員製作開發小程序,而將一些常用的,或者底層的方法進行封裝,並提供給開發人員使用的程序接口。微信小程序是屬於相對封閉的一個環境,獲取或通知外部的程序,或者使用小程序內部的功能,都必須要經過小程序的api調用來實現。