Introduction to Android Hook Framework Xposed

Posted by saariko on Tue, 25 Jun 2019 20:18:35 +0200

To: http://chendd.com/blog/2016/05/15/learn_xposed/


I. Basic knowledge

Xposed is Android A well-known open source framework on the platform. In this framework, we can load many plug-ins App, which can directly or indirectly manipulate ordinary applications and even things on the system. Xposed is, in principle, Hook Zygote, the core process of Android system, is used to modify the running process and result of the program. Speaking of this, some people may ask what is Hook? What is Zygote?

  • Hook (hook), a hook is actually a program segment for processing messages, which is hooked into the system through system calls. Whenever a particular message is sent, the hook program catches the message before reaching the destination window, that is, the hook function gains control first. In this case, the hook function can process (change) the message, or continue to deliver the message without processing, or force the end of the message delivery.

  • Zygote(Android process name), Android system is based on Linux Kernel, and in Linux system, all processes are descendants of init process, that is to say, all processes are directly or indirectly from init process fork. In Android systems, all application processes and system service processes are bred by the Zygote process (fork), which may be why the English version means Zygote of fertilized eggs.

Because the Xposed framework Hook has Android's core process Zygote, and other application startups come from Zygote process fork, it is enough to reach Hook for all application processes on the system.

II. Introduction to Xposed

rovo89 God github home page, as shown in the figure

       

As can be seen from the home page, xposed is mainly composed of three items.

  • Xposed, the C++ part of Xposed, is mainly used to replace / system/bin/app_process and to provide JNI methods for XposedBridge.
  • XposedBridge, the jar file provided by Xposed, loads the jar package during app_process startup, and other Modules are developed based on the jar package.
  • Xposed Installer, Xposed installation package, provides management of Modules based on Xposed framework

xposed has been gradually supporting ART virtual machines, compatible with Android versions 5.0 and above.

III. Use of Xposed

Installation of Android devices above Android 4.0 (with root privileges, it is recommended to use simulators directly) XposedInstaller

Start Xposed Installer and click on Framework

Click on Installation/Update and restart, then click on the Framework to see that both of the bottom two are green to represent the successful installation of the Framework.

We can click on Download to view the hot plug-ins for installation.

After installing the plug-in, click on Module to check activation

After that, the plug-in will need to be restarted before it can take effect. You can download a few plug-ins to play, this article is not the focus of this, do not demonstrate.

IV. Writing Plug-ins

Here we hook our own small login app to get the username and password.

The interface is relatively simple, enter user name password, click login to pop up user input password

Interface Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public EditText et_username;
  // Ordinary reflection does not capture the object when the property is private
  // private  EditText et_password;
  public EditText et_password;
  
  public Button bt_login;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        et_username = (EditText) findViewById(R.id.et_username);
      et_password = (EditText) findViewById(R.id.et_password);
      
      bt_login = (Button) findViewById(R.id.bt_login);
      bt_login.setOnClickListener(this);
    }


    private boolean isCorrectInfo(String username, String password) {
      // Verify that the username password is correct and return true directly
      return true;
    }


  @Override
  public void onClick(View v) {
      switch (v.getId()) {
      case R.id.bt_login:
          if(isCorrectInfo(et_username.getText().toString(), et_password.getText().toString())) {
              // Account Password Check Successfully, Pop up the Current Password
              Toast.makeText(MainActivity.this, "password:"+et_password.getText().toString(), Toast.LENGTH_SHORT).show();
          }
          break;

      default:
          break;
      }
  }

1. Configuration in Android Manifest. XML file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >

  <!-- sign xposed Plug-in unit -->
    <meta-data
        android:name="xposedmodule"
        android:value="true" />
  <!-- Module Description -->
    <meta-data
        android:name="xposeddescription"
        android:value="Sign in hook Example!" />
  <!-- Minimum version number -->
    <meta-data
        android:name="xposedminversion"
        android:value="54" />

</application>

2. Import its jar package

       XposedBridgeApi-.jar After downloading, we need to put Xposed Library is copied to the lib directory (note the lib directory, not the libs directory provided by Android), and then the jar package is added to the Build PATH.

3. Declare the main entry path

You need to create a new xposed_init file in the assets folder and declare the main entry class in it. For example, here our main entry class is

1
com.example.xposedtest.HookUtil

4. Using FindAnd Hook Method Method

This is the most important step, which we have analyzed before. As with the login program we analyzed earlier, we need to hijack the isCorrectInfo method in Hook's com.example.logintest.MainActivity. We use findAndHookMethod provided by Xposed to do the Method Hook operation directly. The XposedBridge.log method is used in its Hook callback to print the password information of the login account into the Xposed log. The specific operation is as follows

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class HookUtil implements IXposedHookLoadPackage{

  @Override
  public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
      // Mark the target app package name
        if (!lpparam.packageName.equals("com.example.logintest"))
            return;
        XposedBridge.log("Loaded app: " + lpparam.packageName);

        // isCorrectInfo(String,String) Method in Hook MainActivity
        // FindAndHook Method (class name of hook method, class Loader, hook method name, hook method parameter, XC_MethodHook)
        XposedHelpers.findAndHookMethod("com.example.logintest.MainActivity", lpparam.classLoader, "isCorrectInfo", String.class,
                String.class, new XC_MethodHook() {

                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                        XposedBridge.log("start hook");
                        XposedBridge.log("Parametric 1 = " + param.args[0]);
                        XposedBridge.log("Parametric 2 = " + param.args[1]);
                    }

                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        XposedBridge.log("End hook");
                        XposedBridge.log("Parametric 1 = " + param.args[0]);
                        XposedBridge.log("Parametric 2 = " + param.args[1]);

                    }
                });


  }

}

5. Run the program to see the effect

Restart the Android device, go to XposedInstaller and click on the log to see, because we used the XposedBridge.log method to print the log, so the log will be displayed here. We found that we need to hijack the account passwords are displayed here again.

Because demo is written by us, we know that the account verification method of hook is CorrectInfo to get the user name and password. What if some program account verification has no encapsulation method? In fact, we can hook some other necessary methods, such as the onClick method of button, and even dynamically change the content of EditText, as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class HookUtil implements IXposedHookLoadPackage{

  @Override
  public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
      // Mark the target app package name
        if (!lpparam.packageName.equals("com.example.logintest"))
            return;
        XposedBridge.log("Loaded app: " + lpparam.packageName);


        // onClick(View v) method in Hook MainActivity
        XposedHelpers.findAndHookMethod("com.example.logintest.MainActivity", lpparam.classLoader, "onClick", View.class, new XC_MethodHook() {

                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    }

                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {

                        Class clazz = param.thisObject.getClass();
                        XposedBridge.log("class name:"+clazz.getName());

                        Field field = clazz.getField("et_password");// Password input box id

                        EditText password = (EditText) field.get(param.thisObject);

                        String string = password.getText().toString();
                        XposedBridge.log("Password = " + string);
                        // Setting a new password
                        password.setText("Change your sister!!");

                    }
                });




  }

}

Click on the login button to find that the contents of the input box have changed

When the EditText password of app was declared private before, it led to the reflection retrieve NoSuchFileException. The reason is that the common reflection can't retrieve private variables. When the EditText declaration is changed to public, it succeeds, or when the EditText declaration can't be changed, the following methods can be used, whether public or private, to retrieve the NoSuchFileException.

1
2
3
4
5
6
7
// The input box is not private and can be obtained by 
// Field = clazz. getField ("et_password"); password input box id

// Get all the properties declared in the class, whether private or public, through the bytecode of the class
Field field = clazz.getDeclaredField("et_password");
// Setting access permissions (familiar with android development experience)
field.setAccessible(true);

4. Summary

Since Hook's own App is successful, system applications are the same as other applications, except that you need to know the open interface or decompile the system to get the corresponding interface. Next time, explain that Hook is not your own application to do something interesting.

Attachment:

This article source code: https://github.com/chendd/XposedTest.git

Official Courses: https://github.com/rovo89/XposedBridge/wiki/Development-tutorial

Official examples: https://github.com/rovo89/XposedExamples

Reference article: http://www.csdn.net/article/1970-01-01/2825462

Topics: Android github Linux xml