Frida用法之函數操作

来源:https://www.cnblogs.com/mysticbinary/archive/2019/12/10/12016364.html
-Advertisement-
Play Games

Frida介面功能介紹 Frida是個so級別的hook框架,它可以幫助開發、安全人員對指定的進程的so模塊進行分析。它主要提供了功能簡單的Python介面和功能豐富的JS介面,使得hook函數和修改so可以編程化,介面中包含了主控端與目標進程的交互介面。 目標進程的交互介面分為: JS介面 功能包 ...


Frida介面功能介紹

Frida是個so級別的hook框架,它可以幫助開發、安全人員對指定的進程的so模塊進行分析。它主要提供了功能簡單的Python介面和功能豐富的JS介面,使得hook函數和修改so可以編程化,介面中包含了主控端與目標進程的交互介面。

目標進程的交互介面分為:

  • JS介面
    功能包括但不限於進程操作、模塊操作、記憶體操作、函數操作、線程操作、網路通信、數據流操作、文件操作、資料庫操作、寄存器操作。
  • Python介面
    提供的功能較少,基本都是用來獲取進程、模塊、函數操作。

Frida功能較多,暫時沒有需求要每個都掌握,我現在的需求就是在程式運行的時候修改函數傳參值、得到函數的返回值這種簡單操作,下麵通過JS配合Python腳本方式對這兩個功能進行探討。


註入Android系統的使用流程

  1. 打開一個APP應用,並跳轉到有你想註入的頁面
  2. 通過adb shell dumpsys activity top,獲取當前 Android 系統中與用戶交互(頂層) Activity 的詳細信息
  3. 反編譯APK文件,根據上一步提供的信息,進行代碼查看,然後定位到想hook的函數,查看的該函數的傳參和返回值
  4. 編寫js註入代碼,運行腳本註入到函數中

步驟1演示 - 打開APP頁面

自己寫的一個Android Demo,下麵有代碼。

步驟2演示 - 獲取頂層Activity信息

adb shell dumpsys activity top

TASK com.example.myapplication id=190
  ACTIVITY com.example.myapplication/.MainActivity 6b2b7a5 pid=31745
    Local Activity e71a071 State:
      mResumed=false mStopped=true mFinished=false
      mChangingConfigurations=false
      mCurrentConfig={1.0 ?mcc?mnc zh_CN ldltr sw411dp w411dp h659dp 420dpi nrml port finger -keyb/v/h -nav/h s.4}
      mLoadersStarted=true
      Active Fragments in 6e3c2de:
        #0: ReportFragment{a0dccbf #0 androidx.lifecycle.LifecycleDispatcher.report_fragment_tag}
          mFragmentId=#0 mContainerId=#0 mTag=androidx.lifecycle.LifecycleDispatcher.report_fragment_tag
          mState=3 mIndex=0 mWho=android:fragment:0 mBackStackNesting=0
          mAdded=true mRemoving=false mResumed=false mFromLayout=false mInLayout=false
          mHidden=false mDetached=false mMenuVisible=true mHasMenu=false
          mRetainInstance=false mRetaining=false mUserVisibleHint=true
          mFragmentManager=FragmentManager{6e3c2de in HostCallbacks{6fc8f8c}}
          mHost=android.app.Activity$HostCallbacks@6fc8f8c
          Child FragmentManager{f8df6d5 in ReportFragment{a0dccbf}}:
            FragmentManager misc state:
              mHost=android.app.Activity$HostCallbacks@6fc8f8c
              mContainer=android.app.Fragment$1@e652eea
              mParent=ReportFragment{a0dccbf #0 androidx.lifecycle.LifecycleDispatcher.report_fragment_tag}
              mCurState=3 mStateSaved=true mDestroyed=false
      Added Fragments:
        #0: ReportFragment{a0dccbf #0 androidx.lifecycle.LifecycleDispatcher.report_fragment_tag}
      FragmentManager misc state:
        mHost=android.app.Activity$HostCallbacks@6fc8f8c
        mContainer=android.app.Activity$HostCallbacks@6fc8f8c
        mCurState=3 mStateSaved=true mDestroyed=false
    ViewRoot:
      mAdded=true mRemoved=false
      mConsumeBatchedInputScheduled=false
      mConsumeBatchedInputImmediatelyScheduled=false
      mPendingInputEventCount=0
      mProcessInputEventsScheduled=false
      mTraversalScheduled=false      mIsAmbientMode=false
      android.view.ViewRootImpl$NativePreImeInputStage: mQueueLength=0
      android.view.ViewRootImpl$ImeInputStage: mQueueLength=0
      android.view.ViewRootImpl$NativePostImeInputStage: mQueueLength=0
    Choreographer:
      mFrameScheduled=false
      mLastFrameTime=64637557 (5732266 ms ago)
    View Hierarchy:
      com.android.internal.policy.PhoneWindow$DecorView{85c75db V.E...... R....... 0,0-1080,1920}
        android.widget.LinearLayout{da91878 V.E...... ........ 0,0-1080,1794}
          android.view.ViewStub{b442b51 G.E...... ......I. 0,0-0,0 #10203b0 android:id/action_mode_bar_stub}
          android.widget.FrameLayout{2df4fb6 V.E...... ........ 0,63-1080,1794}
            androidx.appcompat.widget.ActionBarOverlayLayout{2294b7 V.E...... ........ 0,0-1080,1731 #7f070030 app:id/decor_content_parent}
              androidx.appcompat.widget.ContentFrameLayout{4934424 V.E...... ........ 0,147-1080,1731 #1020002 android:id/content}
                androidx.constraintlayout.widget.ConstraintLayout{94f2b8d V.E...... ........ 0,0-1080,1584}
                  androidx.appcompat.widget.AppCompatTextView{208b142 V.ED..... ........ 191,724-890,861 #7f07008d app:id/tv}
              androidx.appcompat.widget.ActionBarContainer{ec1c553 V.ED..... ........ 0,0-1080,147 #7f070008 app:id/action_bar_container}
                androidx.appcompat.widget.Toolbar{3d27e90 V.E...... ........ 0,0-1080,147 #7f070006 app:id/action_bar}
                  androidx.appcompat.widget.AppCompatTextView{68ff389 V.ED..... ........ 42,38-196,109}
                  androidx.appcompat.widget.ActionMenuView{c749f8e V.E...... ......ID 1080,0-1080,147}
                androidx.appcompat.widget.ActionBarContextView{c1963af G.E...... ......I. 0,0-0,0 #7f07000e app:id/action_context_bar}
        android.view.View{b88f3bc V.ED..... ........ 0,1794-1080,1920 #1020030 android:id/navigationBarBackground}
        android.view.View{2fb3f45 V.ED..... ........ 0,0-1080,63 #102002f android:id/statusBarBackground}
    Looper (main, tid 1) {69f269a}
      (Total messages: 0, polling=false, quitting=false)
    Local FragmentActivity e71a071 State:
      mCreated=true mResumed=false mStopped=true    FragmentManager misc state:
      mHost=androidx.fragment.app.FragmentActivity$HostCallbacks@4a28bcb
      mContainer=androidx.fragment.app.FragmentActivity$HostCallbacks@4a28bcb
      mCurState=2 mStateSaved=true mStopped=true mDestroyed=false

步驟3演示 - 查看代碼

  這個是自己寫的android代碼,沒有混淆。如果你用反編譯的方式打開別人的代碼,大概率是混淆過的,不過也一樣用,無非是將類名、函數名、變數名變成a、b、c...,只是增加看代碼的難度而已,但是調用流程還是一樣的。

public class MainActivity extends AppCompatActivity {

    private TextView testview;
    private String returnvalule;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        testview = findViewById(R.id.tv);

        testview.setText("得分計次1:60 \n");
        returnvalule = addnumber("60");
        testview.append("addnumber()的返回值:" + returnvalule);
    }

    private String addnumber(String nubs){
        testview.append("得分計次2:" + nubs + "\n");
        return "我是預設的返回值⊙_⊙";
    }
}

步驟4演示 - JS配合Python腳本註入

import frida
import sys

jscode = """
/* 這個欄位標記Java虛擬機(例如: Dalvik 或者 ART)是否已載入, 操作Java任何東西的之前,要確認這個值是否為true */
if(Java.available){
    /* 111、222、333 打這些log的目的是看流程走到哪裡 */
    console.log("111");
    
    /* Java.perform(function(){ ... Javascript代碼成功被附加到目標進程時調用,我們核心的代碼要在裡面寫。是個固定格式 */
    Java.perform(function(){
        
        /* Java.use方法用於聲明一個Java類,在用一個Java類之前首先得聲明。比如聲明一個String類,要指定完整的類名var StringClass=Java.use("java.lang.String"); */
        var MainActivity = Java.use("com.example.myapplication.MainActivity");
        console.log("222");
        
        /* 類.函數.overload(參數類型).implementation = function(形參名稱){ */
        MainActivity.addnumber.overload("java.lang.String").implementation = function(nubs){
            console.log("333");
            
            /* 給addnumber函數傳參、得到addnumber函數的返回值 */
            console.log(this.addnumber("77"));
            
            /* 修改addnumber函數的返回值 */
            return "I am Mysticbinary!";
        }
    });

}
"""

def on_message(message, data):
    if message['type'] == 'send':
        print(" {0}".format(message['payload']))
    else:
        print(message)

# 查找USB設備並附加到目標進程
session = frida.get_usb_device().attach('com.example.myapplication')

# 在目標進程里創建腳本
script = session.create_script(jscode)

# 註冊消息回調
script.on('message', on_message)

# 載入創建好的javascript腳本
script.load()

# 讀取系統輸入
sys.stdin.read()

調用說明:

腳本註入說明:

  1. 打開你想註入的界面
  2. 運行上面步驟4的代碼
  3. Android回退到系統主界面,再次進入一次,主要是為了觸發函數
  4. 查看運行結果

代碼運行結果:

app註入結果:

最後總結一下,難點一是操作步驟多,難點二是要看懂要註入的函數的用法,Frida提供的API介面其實非常簡單使用,最後感謝Frida作者開發出這麼優秀的框架,讓我們小白都能做註入。


參考文章

https://www.cnblogs.com/mysticbinary/p/12012935.html
https://frida.re/docs/javascript-api/
https://bbs.pediy.com/thread-226846.htm
https://www.52pojie.cn/forum.php?mod=viewthread&tid=931872


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 關於ip # ip addr 查看ip # vi /etc/sysconfig/network-scrupts/ifcfg-eno 手動設置IP地址 BOOTPROTO=static ONBOOY=yes IPADDR=192.168.233.128 NETMASK=255.255.255.0 GA ...
  • https://sqlserver.code.blog/2019/12/10/different-ag-groups-have-the-exactly-same-group_id-value-if-the-group-names-are-same-and-the-cluster_type-exter ...
  • Redis Cluster 自動化安裝,擴容和縮容 之前寫過一篇基於python的redis集群自動化安裝的實現,基於純命令的集群實現還是相當繁瑣的,因此官方提供了redis-trib.rb這個工具雖然官方的的redis-trib.rb提供了集群創建、 檢查、 修複、均衡等命令行工具,之所個人接受不 ...
  • Linux使用MySQL Yum存儲庫上安裝MySQL 5.7,適用於Oracle Linux,Red Hat Enterprise Linux和CentOS系統。 1、添加MySQL Yum存儲庫 將MySQL Yum存儲庫添加到系統的存儲庫列表中。這是一次性操作,可以通過安裝MySQL提供的RP ...
  • 前言 Hello我又來了,快年底了,作為一個有抱負的碼農,我想給自己攢一個年終總結。自上上篇寫了手動搭建Redis集群和MySQL主從同步(非Docker)和上篇寫了動手實現MySQL讀寫分離and故障轉移之後,索性這次把資料庫中最核心的也是最難搞懂的內容,也就是索引,分享給大家。 這篇博客我會談談 ...
  • ###第一周:R基礎 rm(list = ls()) #ctr+L###矩陣相乘,函數diag()a=matrix(1:12,nrow=3,ncol=4)b=matrix(1:12,nrow=4,ncol=3)a%*%ba=matrix(1:16,nrow=4,ncol=4)diag(a)#返回對角 ...
  • ORACLE資料庫中,我們會使用一些SQL語句找出存在隱式轉換的問題SQL,其中網上流傳的一個SQL語句如下,查詢V$SQL_PLAN的欄位FILTER_PREDICATES中是否存在INTERNAL_FUNCTION: SELECT SQL_ID, PLAN_HASH_VALUEFROM V$SQ... ...
  • 在安裝neo4j之前,需要安裝Java JRE,並配置Java開發環境,然後安裝neo4j服務。 一、CentOS下安裝 1.下載Neo4j 去官網下載最新的neo4j,選擇社區版。地址:https://neo4j.com/download/other-releases/#releases 將本地下 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...