欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

xposed hook框架的使用(二)

程序员文章站 2022-05-12 14:02:29
...

上次埋了个坑,这次我们用一个实际例子来实战练习一下 xposed 的用法

首先创建一个 app 作为我们 hook 的目标,大致就是下面这个样子


xposed hook框架的使用(二)


xposed hook框架的使用(二)

下面是处理逻辑,初学着,以前没接触过 android 开发有哪不对的多多包含

package com.example.login;




import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;




public class MainActivity extends Activity {


	private String name;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        final EditText etUserName = (EditText)findViewById(R.id.userName);
        final EditText etPassword = (EditText)findViewById(R.id.password);
        Button btnLogin = (Button)findViewById(R.id.login);
        
        
        btnLogin.setOnClickListener(new OnClickListener() {
			
			@Override
			//点击登录事件
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				//login 方法判断是否正确
				if(login(etUserName.getText().toString(), etPassword.getText().toString()))
				{
					
					Toast.makeText(getApplicationContext(), "正确", Toast.LENGTH_LONG).show();
					//正确把用户名保存
					name = etUserName.getText().toString();
				}else{
					Toast.makeText(getApplicationContext(), "错误", Toast.LENGTH_LONG).show();
				}
			}
		});
        
    }
    
    //判断是否正确
    private boolean login(String userName,String password)
    {
    	
    	if(userName.equals("tanzui") && password.equals("123"))
    	{
    		return true;
    	}
    	
    	
		return false;
    	
    }


  
}


接下来,把生成的 bin 目录的 apk 文件找出来模拟分析下吧(这里不导出了,偷个懒)

然后用 jeb2 打开(另一神器,既能静态分析,又能动态调试,版权问题自己百度搜索吧)

打开之后是下面这个样子


xposed hook框架的使用(二)

不多做介绍了,自己摸索下应该也就清楚了,双击 Bytecode 变成如下,切换到 Bytecode/Hierarchy,右键 MainActivity 点击 Decompile

xposed hook框架的使用(二)


然后神奇的一幕就出现了,如图

xposed hook框架的使用(二)

你会发现源码出来了,虽然有点不太一样,这应该是我们编译的时候程序优化我们的代码了(笑哭),但是整体流程是对的,当然正式的 app 一般来说都会混淆代码,对代码阅读造成一定影响,咱们现在是实验就不混淆了

梳理下思路,上面代码如果想得到账号和密码只需要 hook “login”方法的两个参数就可以了

接下来咱们接着上一篇留的坑继续补全

打开 com.example.hookproject.demo.HookDemo 类填入一下代码

package com.example.hookproject.demo;


import de.robv.android.xposed.IXposedHookLoadPackage; 
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;

public class HookDemo implements IXposedHookLoadPackage{

	@Override
	public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
		// TODO Auto-generated method stub
		//判断程序是否是我们要 hook 的,不是就跳过
		if(!lpparam.packageName.equals("com.example.login"))
		{
			return;
		}
		
		//hook 指定的 class 中的方法
		XposedHelpers.findAndHookMethod(
				//要 hook 的类,很明显是 MainActivity
				"com.example.login.MainActivity",
				//类加载器
				lpparam.classLoader,
				//要 hook 方法的名称
				"login",
				//参数类型
				String.class,
				//参数类型
				String.class,
				new XC_MethodHook(){
					//在方法运行之前 hook 可在运行之前改变参数的值从而影响运行结果,得不到返回值
					protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
						
					}
					//在方法运行之后 hook 可以得到返回值 这里我们在运行之后就可以了 因为我们需要拿到返回值
					protected void afterHookedMethod(MethodHookParam param) throws Throwable {
						//参数 1 的值
		        		XposedBridge.log("tanzui userName:" + param.args[0]);
		        		//参数 2 的值
		        		XposedBridge.log("tanzui password:" + param.args[1]);
		        		//返回值
		        		XposedBridge.log("tanzui Login:" + param.getResult());
		        		//获取私有属性 name 的值
		        		XposedBridge.log("tanzui name:" + XposedHelpers.getObjectField(param.thisObject, "name"));
		        		
					}
				}
				);
		
	}

}



保存然后运行 - 打开 xposed installer 选择模块 勾选**模块,然后重启手机

xposed hook框架的使用(二)


重启完成之后,打开命令行-使用 adb shell 连接 手机 执行代码 (不知道adb shell 百度搜索一下吧,资料很多)

logcat |grep "tanzui"

等待 log 输出

打开 login app 输入账号 - 密码

cmd 会有以下输出

xposed hook框架的使用(二)


可以很直观的看到 账号 密码以及返回是否正确都被打印了出来 ,细心的朋友可能会发现为什么属性 name 是 null ,这是因为写 login app 的登录验证时把赋值 name 写在了 login 后面 所以hook 到 login方法的时候赋值还没有被执行,再次点 login按钮 会发现 name 有内容了,这是上一次赋的值(笑哭)

xposed hook框架的使用(二)

至此 第一个真正意义上的 hook 就算完成了,有兴趣的朋友还可以在去多多实验一下,下篇准备写一写,dex 分包应用的 hook

下面是工程附件:

(新账号太穷,设了一个积分的下载分,缺分的同学可以按照上一篇一点点来不影响的,分多的同学希望能支持下(害羞))

http://download.csdn.net/download/tanzui/9938680