煎饼 发表于 2019-12-17 09:43:25

微信降版本登录(微信怎么登录低版本)

设备要求  已root的Android手机。  注:下面使用的两个微信安装包,com.tencent.mm.apk为旧版本6.5.16,weixin_new.apk为新版本6.7.3背景  最近在弄一些关于微信的东西,测试过程中,本来打算强行停止后重新启动微信,结果手残点到卸载了。当我重新安装后出现了尴尬的情况,登录的时候,提示微信版本过低,需要安装最新版才能登录。  https://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118020821914-2139113598.png
  但是之前做的一些东西都是基于老版本的微信,所以不能安装新版本,必须想办法在老版本登录才行。
操作过程尝试1、替换版本号  最开始的想法是,既然要验证版本,那我就把旧版本的伪装一下,让它变成新版本的试试。  但是,因为没有时间去仔细分析微信是怎么验证的,于是就抱着侥幸心理,写了个xposed模块替换版本号,  一般情况下是通过以下代码获取版本号的:PackageInfo packageInfo = getPackageManager().getPackageInfo("com.tencent.mm",0);int versionCode = packageInfo.versionCode;String versionName = packageInfo.versionName;
  所以去hook getPackageInfo方法,将其返回的PackageInfo中的versionCode和versionName替换成新版本的值就行,  但是,由下图可知PackageManager是一个抽象接口,https://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118013334855-204229223.png  所以不能直接hook它的getPackageInfo方法,要先获取getPackageManager返回的对象的真实类型,先随便创建一个工程,通过以下代码获取真实的PackageManager类型,Log.v("test", getPackageManager().getClass().toString());

查看日志,可知真实类型为android.app.ApplicationPackageManager,https://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118013852055-1362628589.png  然后通过反编译最新版本的微信,获得versionCode和versionName,https://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118015542798-723952742.png  最后的hook代码如下:https://common.cnblogs.com/images/copycode.gif
if (loadPackageParam.packageName.equals("com.tencent.mm")){    XposedHelpers.findAndHookMethod(            "android.app.ApplicationPackageManager",            loadPackageParam.classLoader,            "getPackageInfo",            String.class,            int.class,            new XC_MethodHook()            {                @Override                protected void afterHookedMethod(MethodHookParam param) throws Throwable                {                  if (param.args.equals("com.tencent.mm"))                  {                        PackageInfo packageInfo = (PackageInfo) param.getResult();                        packageInfo.versionName = "6.7.3";                        packageInfo.versionCode = 1360;                  }                }            });}https://common.cnblogs.com/images/copycode.gif


  编译安装后重启,一边输入帐号密码,一边祈祷,结果还是提示版本过低,https://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118015909320-1479469236.png,
尝试2、pm uninstall -k 命令  想着之前旧版本的都能正常使用,说明只要有登录数据,就可以使用旧版本的,所以想着先用新版本的把帐号登录,然后使用 pm uninstall -k 命令,卸载应用但保留数据,然后安装旧版本的。  先安装一个新版本的微信,https://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118021400978-2023251509.png  登录帐号,https://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118022324461-780325373.pnghttps://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118022210848-1895588423.png
  使用pm uninstall -k com.tencent.mm卸载后安装旧版本的微信,https://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118022420035-1551769871.png  结果打开还是不行,还是提示版本过低,https://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118022948538-60523525.png
  于是怀疑卸载的时候数据被一起删了,根本就没有保留,再次执行pm uninstall -k com.tencent.mm,查看data目录,微信的目录已经不存在了。尝试3、adb install -r 命令  同样先用新版本的把帐号登录,然后使用 adb install -r 命令强制安装,结果还是不行,不能安装比当前版本低的,,, https://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118023631012-842373358.png
尝试4、替换安装目录  既然用 pm uninstall -k 卸载时保留数据不行,那么就尝试手动替换。  首先安装低版本的微信,把安装目录复制一份,然后卸载。https://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118024453131-215820668.png  再安装新版本的微信,并登录帐号。https://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118024838368-833286179.pnghttps://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118024944102-864408331.pnghttps://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118025030489-1908745363.png  用之前保存的旧版本安装目录替换新版本的安装目录,然后重启手机。https://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118025408859-1831784857.png  重启后提示登录错误,重新输入密码即可,  不知道为什么,这个手机在我写这篇博文的时候,关于微信的页面还是新版本的版本号,而我之前弄的另一个手机就是真实的旧版本号,  但是这个手机系统设置中微信的版本号已经变成旧版本的了,也不影响使用。https://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118030202140-1023179853.pnghttps://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118030255278-2034156580.pnghttps://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118030352131-519496116.png  另一个手机的,https://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118035416491-910298269.png
自动化程序   把之前替换的过程写了个自动替换的程序,代码如下,其中使用的ShellUtils在之前的一篇【Android手机插上usb能充电但不能识别的一种解决方法】能找到:https://common.cnblogs.com/images/copycode.gif
package com.example.wxreversion;

import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.io.File;

public class MainActivity extends AppCompatActivity
{
    Handler handler;
    TextView textView;


    private void LogV(String s)
    {
      Log.v("test", s);
    }

    private void textAppend(final String s)
    {
      LogV("textAppend:" + s);
      handler.post(new Runnable()
      {
            @Override
            public void run()
            {
                LogV("run:" + s);

                textView.setText(textView.getText() + s);
            }
      });
    }

    private String getPath()
    {
      String path = null;
      textAppend("-----------------------------\n");


      if (!ShellUtils.checkRootPermission())
      {
            textAppend("获取root权限失败,请在设置中授予权限!\n");
            return path;
      }

      path = ShellUtils.execCommand("pm path com.tencent.mm", true).successMsg;
      if (path != null)
      {
            try
            {
                path = path.substring(path.indexOf('/'), path.lastIndexOf('/'));
            } catch (Throwable throwable)
            {
                path = null;
            }
      }

      if (path == null)
      {
            textAppend("未找到微信安装目录,请先安装!\n");
      } else
      {
            textAppend("找到安装目录:" + path + "\n");
      }

      return path;
    }

    private boolean isEnpty(String string)
    {
      if (string == null || string.length() == 0)
      {
            return true;
      }
      return false;
    }

    private void putResult(ShellUtils.CommandResult result)
    {
      textAppend("返回码:" + result.result + "\n");

      if (!isEnpty(result.successMsg))
      {
            textAppend(result.successMsg + "\n");
      } else if (!isEnpty(result.errorMsg))
      {
            textAppend("错误消息:" + result.errorMsg + "\n");
      }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      handler = new Handler();

      textView = (TextView) findViewById(R.id.textView);
      textView.setMovementMethod(ScrollingMovementMethod.getInstance());

      ((Button) findViewById(R.id.button1)).setOnClickListener(new View.OnClickListener()
      {
            @Override
            public void onClick(View v)
            {

                new Thread()
                {
                  @Override
                  public void run()
                  {
                        String path = getPath();
                        if (path == null)
                        {
                            return;
                        }
                        textAppend("正在保存安装目录!\n");
                        ShellUtils.CommandResult result = ShellUtils.execCommand("cp -af " + path + " /data/local/tmp/com.tencent.mm", true);
                        putResult(result);
                        if (!isEnpty(result.errorMsg))
                        {
                            return;
                        }

                        textAppend("正在卸载微信!\n");
                        result = ShellUtils.execCommand("pm uninstall com.tencent.mm", true);//-k无用
                        putResult(result);
                        if (!isEnpty(result.errorMsg))
                        {
                            return;
                        }

                        textAppend("请安装新版微信,并在登录成功后点击【覆盖安装文件并重启】按钮!\n");
                  }
                }.start();

            }
      });


      ((Button) findViewById(R.id.button2)).setOnClickListener(new View.OnClickListener()
      {
            @Override
            public void onClick(View v)
            {

                new Thread()
                {
                  @Override
                  public void run()
                  {
                        String path = getPath();
                        if (path == null)
                        {
                            return;
                        }

                        textAppend("正在检查是否有备份的安装文件!\n");
                        if (!new File("/data/local/tmp/com.tencent.mm").exists())
                        {
                            textAppend("不存在备份的安装文件,请先安装低版本微信后点击【覆盖安装文件并重启】按钮!\n");
                            return;
                        }

                        textAppend("已有备份的安装文件,正在删除当前的安装目录!\n");
                        ShellUtils.CommandResult result = ShellUtils.execCommand("rm -rf " + path + "/*", true);
                        putResult(result);
                        if (!isEnpty(result.errorMsg))
                        {
                            return;
                        }


                        textAppend("正在覆盖安装目录!\n");
                        result = ShellUtils.execCommand("cp -af /data/local/tmp/com.tencent.mm/* " + path, true);
                        ShellUtils.execCommand("rm -rf /data/local/tmp/com.tencent.mm", true);
                        putResult(result);
                        if (!isEnpty(result.errorMsg))
                        {
                            return;
                        }

                        textAppend("系统将在10秒后重启!\n");


                        try
                        {
                            sleep(10 * 1000);
                            handler.post(new Runnable()
                            {
                              @Override
                              public void run()
                              {
                                    ShellUtils.execCommand("reboot", true);
                              }
                            });
                        } catch (InterruptedException e)
                        {
                            e.printStackTrace();
                        }
                  }
                }.start();

            }
      });

      textView.append("-----------------------------\n");
      textView.append("该应用需要root权限!\n");
      if (ShellUtils.checkRootPermission())
      {
            textView.append("获取root权限成功!\n");
      } else
      {
            textView.append("获取root权限失败,请在设置中授予权限!\n");
      }


    }
}https://common.cnblogs.com/images/copycode.gif


运行如下:先安装旧版本微信,https://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118031441318-1187832951.png运行该程序,点击左边的【保存安装文件并卸载】按钮,https://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118031829641-1272206719.png  安装新版本微信并登录,https://img2018.cnblogs.com/blog/1064618/201811/1064618-20181118032116325-1757895425.png  点击右边的【覆盖安装文件并重启】按钮,  重启后重新输密码登录即可。
完整代码 wxreversion.rar安装包在release目录中
转自:https://www.cnblogs.com/JOUO4/p/9976939.html
页: [1]
查看完整版本: 微信降版本登录(微信怎么登录低版本)