使用xposed hook 登录账户和密码

准备工作

  1. 一台已root过的手机

  2. 安装Xposed Installe

  3. 下载XposedBridge.jar(https://jcenter.bintray.com/de/robv/android/xposed/api/)

  4. 下载apktool,dex2jar-2.0,jdgui等反编译工具

  5. 下载 铂涛旅行app(我们将对该app进行反编译,你也可下载其它app)

  6. 下载dumpDex(用于脱壳)

脱壳(由于铂涛旅行app使用360加壳了,所以我们需要先脱壳)&查看源码

  1. 安装dumpDex.apk

  2. 在Xposed Installe启用dumpDex模块,重启手机

  3. 打开需要脱壳的apk

  4. 使用shell命令把/data/data/{package_name}/dump目录下的.dex文件拷贝出来

  5. 使用dex2jar将dex文件转成jar文件

  6. 使用jdgui查看jar文件,找到需要hook的代码

创建项目

Step 1: 修改AndroidManifest.xml,在application标签下增加如下代码

image.png

Step 2: gradle添加依赖

compileOnly files('libs/api-82.jar')

Step 3: 编写代码

image.png

从源码我们能看到只要我们Hook了LoginForm构造方法便可以获取到未加密的登录账号和密码


  class XposedHook : IXposedHookLoadPackage{
      override fun handleLoadPackage(loadPackageParam: XC_LoadPackage.LoadPackageParam?) {
          if(loadPackageParam!!.packageName.equals("com.plateno.botaoota")){ //找到需要hook的包名
              hookBotao(loadPackageParam)
          }
      }

      fun hookBotao(loadPackageParam: XC_LoadPackage.LoadPackageParam?){

          XposedHelpers.findAndHookMethod("com.stub.StubApp",loadPackageParam!!.classLoader,"attachBaseContext",Context::class.java,object :XC_MethodHook(){
              override fun afterHookedMethod(param: MethodHookParam?) { //由于被360加固过,所以需要hook attachBaseContext来获取类加载器
                  XposedBridge.log("afterHookedMethod")
                  val context: Context = param!!.args[0] as Context
                  val classLoader: ClassLoader = context.classLoader
                  hookUserNameAndPwd(classLoader)
                  hookReq(classLoader)
                  hookReqParam(classLoader)
                  hookRsp(classLoader)
              }
          })
      }

      fun hookUserNameAndPwd(classLoader: ClassLoader){
          XposedHelpers.findAndHookConstructor("com.bestwehotel.app.whlogin.model.LoginForm",classLoader, String::class.java,String::class.java,object :XC_MethodHook(){
              override fun afterHookedMethod(param: MethodHookParam?) { //hook 构造方法获取登录账号和密码
                  XposedBridge.log("botao username=========>"+param!!.args[0])
                  XposedBridge.log("botao password=========>"+param.args[1])
              }
          })
      }

      fun hookReq(classLoader: ClassLoader){ //hook okhttp 请求地址等信息
          XposedHelpers.findAndHookMethod("okhttp3.RealCall",classLoader,"getResponseWithInterceptorChain",object :XC_MethodHook(){
              override fun afterHookedMethod(param: MethodHookParam?) {
                  val requestField = param!!.result::class.java.getDeclaredField("request")
                  requestField.isAccessible = true
                  val requestObj = requestField.get(param.result)
                  val reqStrMethod = requestObj::class.java.getMethod("toString")
                  val reqStr = reqStrMethod.invoke(requestObj)
                  XposedBridge.log("req base info =========>" + reqStr)
              }
          })
      }

      fun hookReqParam(classLoader: ClassLoader){ //hook okhttp 请求参数
          XposedHelpers.findAndHookConstructor("okhttp3.FormBody",classLoader, List::class.java,List::class.java,object :XC_MethodHook(){
              override fun afterHookedMethod(param: MethodHookParam?) {
                  val names: ArrayList<*> = param!!.args[0] as ArrayList<*>
                  val values: ArrayList<*> = param.args[1] as ArrayList<*>
                  XposedBridge.log("============ req param ==========")
                  for (i in names.indices){
                      XposedBridge.log(names[i] as String + "=" + values[i] as String)
                  }
              }
          })
      }

      fun hookRsp(classLoader: ClassLoader){ //hook okhttp 响应
          XposedHelpers.findAndHookMethod("okhttp3.ResponseBody",classLoader,"string",object :XC_MethodHook(){
              override fun afterHookedMethod(param: MethodHookParam?) {
                  XposedBridge.log("rsp info ==========>" + param!!.result)
              }
          })
      }
  }

Demo

XposedDemo

你可能感兴趣的:(使用xposed hook 登录账户和密码)