Getting Started with Android Hook Framework Xposed

 Original address: http://blog.csdn.net/d3soft/article/details/53224249

1. Basic knowledge

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

  • Hook (hook), a hook is actually a program segment that processes messages, which is hooked into the system through system calls. Whenever a specific message is sent, the hook program first captures the message before it reaches the destination window, that is, the hook function first gets the control right. At this time, 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), the Android system is based on the Linux kernel, and in the Linux system, all processes are descendants of the init process, that is to say, all processes are directly or indirectly fork of the init process of. In the Android system, all application processes and system service processes SystemServer are forked by the Zygote process. This may be the reason why the name Zygote, which means fertilized egg in English, is named.

       Since the Xposed framework hooks the Android core process Zygote, and other applications start from the fork of the Zygote process, it is enough to achieve hooks for all application processes on the system.

2. Introduction to Xposed

       rovo89 Great God github homepage, as shown

       

It can be roughly seen from the homepage that xposed is mainly composed of three projects

  • Xposed, the C++ part of Xposed, is mainly used to replace /system/bin/app_process and provide JNI methods for XposedBridge
  • XposedBridge, the jar file provided by Xposed, the jar package will be loaded during app_process startup, and the development of other Modules is based on the jar package
  • XposedInstaller, Xposed installation package, provides management of Modules based on Xposed framework

xposed currently supports ART virtual machine gradually, compatible with android 5.0 and above

3. Xposed use

       Install XposedInstaller on Android devices above Android 4.0 (root permission is required, emulator is recommended)

Start XposedInstaller and click [Frame]

 

Click [Install/Update] and restart, and then click on the frame to see that the two under activation are all green, which means that the frame is installed successfully

 

We can click [Download] to view popular plugins for installation

After installing the plug-in, click [Module] to check and activate

After that, restart is required for the plug-in to take effect. You can download a few plug-ins for fun. This article is not focused on this, so I won’t demonstrate it.

Four. Write plug-ins

Here we hook a small login app written by ourselves to get the username and password.

The interface is relatively simple, enter the user name and password and click login to pop up the password entered by the user

 

Interface code

  public EditText et_username; // 属性为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) { // 校验用户名密码是否正确,直接返回true 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())) { // 帐号密码校验成功,弹出当前密码 Toast.makeText(MainActivity.this, "password:"+et_password.getText().toString(), Toast.LENGTH_SHORT).show(); } break; default: break; } }

1. Configure in the AndroidManifest.xml file

  <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <!-- 标记xposed插件 --> <meta-data android:name="xposedmodule" android:value="true" /> <!-- 模块描述 --> <meta-data android:name="xposeddescription" android:value="登录hook例子!" /> <!-- 最低版本号 --> <meta-data android:name="xposedminversion" android:value="54" /></application>

2. Import its jar package

       XposedBridgeApi-.jar , after downloading, we need to copy Xposed Library to the lib directory (note that it is the lib directory, not the libs directory provided by Android), and then add this jar package to the Build PATH.

3. Declare the main entrance path

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

1 com.example.xposedtest.HookUtil

 

4. Use the findAndHookMethod method Hook

       This is the most important step, and all of our previous analysis needs to be performed at this step. For the login program we analyzed before, we need to hijack, that is, we need to Hook the isCorrectInfo method in its com.example.logintest.MainActivity. We use findAndHookMethod provided by Xposed to directly perform MethodHook operations. Use the XposedBridge.log method in its Hook callback to print the login account password information to the Xposed log. The specific operation is as follows

  public class HookUtil implements IXposedHookLoadPackage
 {
    @Override public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable { // 标记目标app包名 if (!lpparam.packageName.equals("com.example.logintest")) return; XposedBridge.log("Loaded app: " + lpparam.packageName); // Hook MainActivity中的isCorrectInfo(String,String)方法 // findAndHookMethod(hook方法的类名,classLoader,hook方法名,hook方法参数...,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("开始hook"); XposedBridge.log("参数1 = " + param.args[0]); XposedBridge.log("参数2 = " + param.args[1]); } @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { XposedBridge.log("结束hook"); XposedBridge.log("参数1 = " + param.args[0]); XposedBridge.log("参数2 = " + param.args[1]); } }); }}

5. Run the program and check the effect

 

       Restart the Android device, enter XposedInstaller and click [Log] to view, because we used the XposedBridge.log method to print the log before, so the log will be displayed here. We found that the account and password we need to hijack are displayed here again.

 

       Since the demo is written by ourselves, we know the account verification method isCorrectInfo to hook it to get the user name and password. What if there is no package method for account verification in some programs? In fact, we can hook some other necessary methods, such as the button's onClick method, and even dynamically change the content of EditText, as follows:

  public class HookUtil implements IXposedHookLoadPackage{ @Override public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable { // 标记目标app包名 if (!lpparam.packageName.equals("com.example.logintest")) return; XposedBridge.log("Loaded app: " + lpparam.packageName); // Hook MainActivity中的onClick(View v)方法 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");// 密码输入框 id EditText password = (EditText) field.get(param.thisObject); String string = password.getText().toString(); XposedBridge.log("密码 = " + string); // 设置新密码 password.setText("改你妹啊!!"); } }); }}

 

       Click the login button and find that the content of the input box has changed

 

       When the previous login app password EditText was declared as private, the reflection acquisition reported NoSuchFileException. The reason was that ordinary reflection could not obtain private variables. When the EditText declaration was changed to public, it succeeded, or when the EditText declaration could not be changed, the following methods can be used, regardless of public Privately available

1234567 // 输入框不为私有private 可通过以下方式获取 // Field field = clazz.getField("et_password");// 密码输入框 id// 通过类的字节码得到该类中声明的所有属性,无论私有或公有Field field = clazz.getDeclaredField("et_password");// 设置访问权限(这点对于有过android开发经验的可以说很熟悉)field.setAccessible(true);

4. Summary

       Now that you can successfully Hook your own App, the same applies to system applications and other applications, except that you need to know the system public interface or decompile to obtain the corresponding interface. Next time, I will explain that Hook is not your own application to do something fun.

Attach:

Source code of this article:  https://github.com/chendd/XposedTest.git

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

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

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

Guess you like

Origin blog.csdn.net/zhengjian1996/article/details/112937269