Android reverse learning Frida reverse and packet capture practical study notes (continuously updated)

Learning materials: "Android Frida Reverse and Packet Capture Actual Combat" Chen Jialin / Author

basic environment

  1. Install Android Studio and configure adb
  2. A rooted real machine or an Android virtual machine

Chapter 3 Frida reverse entry Java layer hook

3.1 Frida basics

3.1.3 Basic knowledge of Frida

Frida has two modes of operation

  1. CLI (command line mode)
    injects js code into the process through the command line
  2. RPC mode
    injects js code into the process through python, essentially using js code for hook

There are two ways for frida to operate App

  1. In spwan mode
    , the right to start the app is handed over to frida. Even if the target app is started, it will be
    restarted by frida. The -f parameter can be specified to operate the app in spwan mode
  2. The attach mode
    app has been started, and frida injects the program through ptrace to execute the hook. Frida defaults to the attach mode operation app

3.1.4Frida IDE configuration

  1. Install node and npm environment
  2. git download frida-agent-example repository
git clone https://github.com/oleavr/frida-agent-example.git 下载frida-agent-example仓库
cd frida-agent-example/
npm install

Use vscode to open, create a folder in the frida-agent-example folder to write scripts
insert image description here

3.2 Getting started with frida script

3.2.1 The concept of frida script

Example:

setTimeout(function(){
    
    
    Java.perform(function(){
    
    
        console.log("hello,world")
    })
})

代码分析:
1. 调用setTimeout方法将匿名函数注册到js运行库中
2. 在函数中调用Java.perform方法,将匿名函数注册到App的java运行库中,并执行函数

After running frida-server on the mobile phone, you can use the frid-ps -U command to view the running process
Please add a picture description
and then use frida -U -l test0.js android.process.media to inject the script into the process, and you can find that helloworld is printed after injection
Please add a picture description

In the above parameters, -U specifies the usb device, -l specifies the path where the injection script is located, and the last androdi.process.media is the name of the process running on the device

3.2.2 Java layer hook basics

1. A preliminary study on hooks

android studio project code

package com.example.hooktest1;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.util.Locale;

public class MainActivity extends AppCompatActivity {
    
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        int x=0,y=0;
        while(true){
    
    
            try {
    
    
                Thread.sleep(1000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            fun(x,y);
            x++;y++;
        }
    }
    void fun(int x,int y)
    {
    
    
        Log.d("sum=",String.valueOf(x+y));
    }
}

Running results: the android studio console will continue to output x+y, and x and y will increase gradually
Please add a picture description

hook script code:

function main(){
    
    
    console.log("Script loaded success")
    //Java.perform是frida的api函数,可以将其中的脚本注入到java运行库,参数是一个匿名函数
    //函数的主体内容是监控和修改java函数逻辑的主题内容,任何针对java层的操作都必须在这个api函数中
    Java.perform(function(){
    
    
        console.log("Inside java perform!")
        //java.use获取hook函数所在类的类名
        var Mainactivity=Java.use('com.example.hooktest1.MainActivity')
        console.log("Java.use.success!")
        //通过.连接函数名,比如这里的函数名是fun,表示想hookfun函数
        //implementation表示实现该函数,也就是hook掉,这里可以写自己的函数
        Mainactivity.fun.implementation=function(x,y)
        {
    
    
            console.log("x=",x,"y=",y,"x+y=",x+y)   //打印参数,这里应该是函数原本没有被修改时的参数,即函数正常执行时的参数情况
            var retvalue=this.fun(666,66)           //再次调用原函数并且传递原本的参数fun,即重新执行原函数,在这里就可以修改参数
            return retvalue      //返回函数返回值,返回值最好不要修改类型,否则可能出错
        }
    })
}
//参数是要被执行的函数,例如传入main,表示frida注入app后立刻执行main
//setTimeout可以指定frida注入app多久之后执行函数,用于延时注入
setImmediate(main)

Inject the script into the process frida -U -l test0.js com.example.hooktest1
You can see that after the injection, the command console will output the content of the js script function
Please add a picture description
Look at the android studio command console, you can find that the console has been outputting sum=: 732
Indicates that calling this.fun(666,66) in the script is successful
Please add a picture description

2. The hook of the overloaded function

Slightly modified code:

package com.example.hooktest1;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
    
    
    private String total="hello";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        int x=0,y=0;
        while(true){
    
    
            try {
    
    
                Thread.sleep(1000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            fun(x,y);
            x++;y++;
            Log.d("hooktest:",fun("HelloWorld!"));
        }
    }
    void fun(int x,int y)
    {
    
    
        Log.d("sum=",String.valueOf(x+y));
    }
    String fun(String s){
    
    
        return s.toLowerCase();
    }

Program running result:
Please add a picture description

hook script:

//定位重载函数,使用overload即可,overload内指定重载函数参数类型,如果函数有返回值要注意返回
 function main(){
    
    
    console.log("Loaded sucess!")
    Java.perform(function(){
    
    
        console.log("Inside java perform")
        var activity=Java.use("com.example.hooktest1.MainActivity")
        console.log("定位activity成功")
        activity.fun.overload('java.lang.String').implementation=function(x){
    
    
            console.log("hook fun string=",x)
            return x
        }
        activity.fun.overload('int','int').implementation=function(x,y){
    
    
            console.log("x=",x,"y=",y)
           var ret= this.fun(66,55)
           return ret;
        }
    })
 }
 setImmediate(main)

hook result
Please add a picture description

Console:
Please add a picture description

3.2.3 Java layer active call

The above implementation is passive call: that is, the function is executed with the normal logic of the app.
Active call can directly call the key function without the need for the app to execute the function.
Here are two situations:

  1. Class function (static method) Just use Java.use to find the class where the function is located
  2. Instance method (dynamic method) Use the Java.choose api function to find the specified class instance in the java heap

1. Active call example 1

Program code:
Added two methods of secret and staticSecret

package com.example.hooktest1;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.util.Locale;

public class MainActivity extends AppCompatActivity {
    
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        int x=0,y=0;
        while(true){
    
    
            try {
    
    
                Thread.sleep(1000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            fun(x,y);
            x++;y++;
            Log.d("hooktest:",fun("HelloWorld!"));
        }
    }
    void fun(int x,int y)
    {
    
    
        Log.d("sum=",String.valueOf(x+y));
    }
    String fun(String s){
    
    
        return s.toLowerCase();
    }
    void secret(){
    
    
        Log.d("this is secret","find secret func!");
    }
    static void staticSecret(){
    
    
        Log.d("this is staticSecret","Find static!");
    }
}

Program execution result:
Please add a picture description

hook script:

function main(){
    
    
    Java.perform(function(){
    
    
        console.log("Inside java perform")
        var MainActivity=Java.use("com.example.hooktest1.MainActivity")
            
        MainActivity.staticSecret()
        //动态函数主动调用
        //java.choose先从内存中寻找类的实例对象,然后再调用实例对象的函数
        Java.choose('com.example.hooktest1.MainActivity',{
    
    
            onMatch: function(instance){
    
    
                console.log("instance found",instance)
                instance.secret()
            },
            onComplete: function(){
    
    
                console.log('search Complete')
            }
        })

    })
}
setImmediate(main)

Hook results
You can see that the class and address of the instance object are successfully printed
Please add a picture description

The console can see that the two functions secret and staticSecret have been successfully called
Please add a picture description

Note: The results of calling these two functions are in the android studio console, not in the frida console. The frida console outputs the content in the js script.

2. Active call example 2

Slightly modify the above program code, add two private variables, try to hook the variable value

package com.example.hooktest1;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.util.Locale;

public class MainActivity extends AppCompatActivity {
    
    
    private String total="hello";
    private int count=0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        int x=0,y=0;
        while(true){
    
    
            try {
    
    
                Thread.sleep(1000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            fun(x,y);
            x++;y++;
            Log.d("hooktest:",fun("HelloWorld!"));
        }
    }
    void fun(int x,int y)
    {
    
    
        Log.d("sum=",String.valueOf(x+y));
    }
    String fun(String s){
    
    
        return s.toLowerCase();
    }
    void secret(){
    
    
        total+="call"+count;
        count++;
        Log.d("this is secret","find secret func!");
    }
    static void staticSecret(){
    
    
        Log.d("this is staticSecret","Find static!");
    }
}

Program running result:
Please add a picture description

hook script:

//调用secret函数,需要控制台手动进行,
function callSecretFunc(){
    
    
    Java.perform(function(){
    
    
        Java.choose('com.example.hooktest1.MainActivity',{
    
    
            onMatch:function(instance){
    
    
                instance.secret()
            },
            onComplete:function(){
    
    

            }
        })
})
}

//获取total的值
function getTotalValue(){
    
    
    Java.perform(function(){
    
    
        Java.choose('com.example.hooktest1.MainActivity',{
    
    
            onMatch:function(instance){
    
    
                console.log("find instance=",instance)
                console.log("totalAddr=",instance.total)//获取类变量的值要使用.value,total本身是一个引用类型
                console.log("total=",instance.total.value)
            },
            onComplete:function(){
    
    
                console.log("search end")
            }
        })
    })
}
setImmediate(getTotalValue)

The hook result
shows that the program first calls the getTotalValue function and outputs the value of total.
Then we call the script function callSecretFunc() in the frida console to call the secret function to modify the value of total.
Call getTotalValue again to output the value of total and find that the modification is successful.
Please add a picture description

Summarize:

  1. To get the instance variable in the class, you need to use .value to get its value. If you can’t get the value by printing directly (you can get information about the variable, because total itself is a reference type)
  2. In the frida console, we can repeatedly call the script function to achieve the purpose of repeatedly calling the program function

Chapter 4 Objection Quick Start

4.2 Installation and use of Objection

4.2.1 objection installation

pip install -U objection

Note: Since frida is updated quickly, it is necessary to ensure that the objection version is released after frida. The latest objection version is 1.11.0, the corresponding frida version is up to 14.2.14, and frida-tools is 9.2.2

4.2.2 objection use

1. Inject process into REPL

Objection is connected to the device through USB by default, and there is no need to use the -U parameter to specify usb
to 'set' the application demonstration injection process command like Frida: objection -g com.android.settings explore
Successful injection will display the following information:
Please add a picture description

In this way, you have successfully entered the REPL interface of objection, and you can enter exit to exit

2. Common commands:

Spacebar prompts for commands
Please add a picture description

  1. help If you don't know the effect of the current command, you can use help before the command, and the explanation information of the command will be output
    Please add a picture description

  2. The jobs command
    jobs list displays the current job
    jobs kill deletes the job
    Please add a picture description

  3. frida command
    View frida information
    Please add a picture description

  4. Memory roaming related commands
    (1) android hooking list classes
    print all classes in memory
    Please add a picture description

    (2) android hooking search classes key
    searches for all classes containing the keyword key
    Please add a picture description

    (3) android hooking search methods key
    searches for all methods that contain the keyword key
    Please add a picture description

    (4) android hooking list class_methods classname
    View all methods of the class named classname
    Please add a picture description

    (5) android hooking list activities (services receivers providers)
    print four major components, list all the activity activities of the process (service receiver provider)
    Please add a picture description

  5. Hook related commands
    android hooking watch class_method methodName
    hook the specified method
    Please add a picture description

Continuously updating...

Guess you like

Origin blog.csdn.net/OrientalGlass/article/details/130903086