下沙论坛

标题: 微信降版本登录(微信怎么登录低版本) [打印本页]

作者: 煎饼    时间: 2019-12-17 09:43
标题: 微信降版本登录(微信怎么登录低版本)
设备要求
  已root的Android手机。
  注:下面使用的两个微信安装包,com.tencent.mm.apk为旧版本6.5.16,weixin_new.apk为新版本6.7.3
背景
  最近在弄一些关于微信的东西,测试过程中,本来打算强行停止后重新启动微信,结果手残点到卸载了。当我重新安装后出现了尴尬的情况,登录的时候,提示微信版本过低,需要安装最新版才能登录。
  

5 S- y; s; L3 i) G: @7 k$ n* ~& p
  但是之前做的一些东西都是基于老版本的微信,所以不能安装新版本,必须想办法在老版本登录才行。
& t' [* c" M& r2 U' J6 |4 V
操作过程尝试1、替换版本号
  最开始的想法是,既然要验证版本,那我就把旧版本的伪装一下,让它变成新版本的试试。
  但是,因为没有时间去仔细分析微信是怎么验证的,于是就抱着侥幸心理,写了个xposed模块替换版本号,
  一般情况下是通过以下代码获取版本号的:
PackageInfo packageInfo = getPackageManager().getPackageInfo("com.tencent.mm",0);int versionCode = packageInfo.versionCode;String versionName = packageInfo.versionName;
: u+ C' N7 f$ a
  所以去hook getPackageInfo方法,将其返回的PackageInfo中的versionCode和versionName替换成新版本的值就行,
  但是,由下图可知PackageManager是一个抽象接口,
  所以不能直接hook它的getPackageInfo方法,要先获取getPackageManager返回的对象的真实类型,先随便创建一个工程,通过以下代码获取真实的PackageManager类型,
Log.v("test", getPackageManager().getClass().toString());  T, D% B, y& H8 z2 h- c4 d  ^( e

$ Y. y( W$ ]! H5 N$ I2 N, Y% k! K) ?- \查看日志,可知真实类型为android.app.ApplicationPackageManager,
  然后通过反编译最新版本的微信,获得versionCode和versionName,
  最后的hook代码如下:
[url=][/url]1 l' S, D; M/ X* d
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[0].equals("com.tencent.mm"))                    {                        PackageInfo packageInfo = (PackageInfo) param.getResult();                        packageInfo.versionName = "6.7.3";                        packageInfo.versionCode = 1360;                    }                }            });}[url=][/url]
& b2 l3 f( u9 m5 C+ |9 V5 D

6 ~, _6 g4 L, U: b+ B5 \; o% [9 _0 ^8 E" @1 D& k
  编译安装后重启,一边输入帐号密码,一边祈祷,结果还是提示版本过低,

5 y5 r& S8 m0 l6 p& z, O$ i/ Y( l尝试2、pm uninstall -k 命令
  想着之前旧版本的都能正常使用,说明只要有登录数据,就可以使用旧版本的,所以想着先用新版本的把帐号登录,然后使用 pm uninstall -k 命令,卸载应用但保留数据,然后安装旧版本的。
  先安装一个新版本的微信,
  登录帐号,
  V* A/ n" g" [. V% k
  使用pm uninstall -k com.tencent.mm卸载后安装旧版本的微信,
  结果打开还是不行,还是提示版本过低,

( c/ K  @2 J- ]& _  @+ C6 M) k4 q
  于是怀疑卸载的时候数据被一起删了,根本就没有保留,再次执行pm uninstall -k com.tencent.mm,查看data目录,微信的目录已经不存在了。
尝试3、adb install -r 命令
  同样先用新版本的把帐号登录,然后使用 adb install -r 命令强制安装,结果还是不行,不能安装比当前版本低的,,,
+ N* I3 a. l% K+ B, [
尝试4、替换安装目录
  既然用 pm uninstall -k 卸载时保留数据不行,那么就尝试手动替换。
  首先安装低版本的微信,把安装目录复制一份,然后卸载。
  再安装新版本的微信,并登录帐号。
  用之前保存的旧版本安装目录替换新版本的安装目录,然后重启手机。
  重启后提示登录错误,重新输入密码即可,
  不知道为什么,这个手机在我写这篇博文的时候,关于微信的页面还是新版本的版本号,而我之前弄的另一个手机就是真实的旧版本号,
  但是这个手机系统设置中微信的版本号已经变成旧版本的了,也不影响使用。
  另一个手机的,

% E5 \" W' f1 V, k1 J1 \; H自动化程序
  把之前替换的过程写了个自动替换的程序,代码如下,其中使用的ShellUtils在之前的一篇【Android手机插上usb能充电但不能识别的一种解决方法】能找到:
[url=][/url]
3 E2 W0 m0 r; Q; ]% |package com.example.wxreversion;: s; `! U$ ], p0 I9 d! c
5 P4 Q3 f0 w& {6 V$ d
import android.os.Handler;
, O$ v2 m$ C5 ~; n6 S- I" `import android.support.v7.app.AppCompatActivity;' T8 ^. Q. V2 B' ]
import android.os.Bundle;
6 B) S0 U5 N8 D3 Y, l; |+ qimport android.text.method.ScrollingMovementMethod;
1 S" S4 Z8 z9 R0 S# O1 Kimport android.util.Log;
- b' {5 T/ y! ^2 cimport android.view.View;: p& i$ }  E, X( Z! d
import android.widget.Button;* l8 Y" R1 F6 H
import android.widget.TextView;: g3 ?$ w, w: @( c; ~" k7 ^% \

% g! d' e# M9 U. c% vimport java.io.File;+ n9 v$ ~/ W, t4 J% N

, W9 [0 V( _" _, dpublic class MainActivity extends AppCompatActivity8 Q" T$ _# ~2 M+ y+ B
{
: l6 J5 P+ T) N) z1 @& j    Handler handler;
9 z( M- t) y  I6 D; `( B    TextView textView;
0 l" G4 l5 o2 Y7 ]' g. i4 k0 E' Q: z* {# @2 D  k

6 m  n4 ~- o+ @* ~; O0 \1 M    private void LogV(String s)
" _( U8 |  `$ p& E    {0 Y( b0 k/ Z5 w/ y' w/ H* p* K
        Log.v("test", s);
' F4 @9 e- a% _0 J+ O! D    }
$ ^% d. t1 u# K3 I6 c+ k, ]! z0 d8 n3 C
    private void textAppend(final String s)# e: J/ X" ]4 A9 l
    {
# o- a, i, _  W) h+ f: ~        LogV("textAppend:" + s);
2 c7 g$ C; c/ C$ e# ~2 G- w        handler.post(new Runnable()
3 R" _  r9 d4 p8 S* u        {
: b' M# }9 I& Y% T9 A/ f7 B            @Override8 N5 J/ d  b' q( s# M! \) K
            public void run()
! ]; p- G! J% P2 ]+ N- r# b            {
- r  X3 L+ b- v7 J& H* g% u; r                LogV("run:" + s);' w2 L4 m5 q+ H- @  S4 l* R& O4 X" O" F

% t4 G9 \% E! E1 J                textView.setText(textView.getText() + s);3 F1 J; {: {0 y6 W2 f
            }
! ^+ _2 j' W. V0 v& j        });  ]: L, q; J9 {0 {3 I
    }4 a6 i' P% E' c$ B) |) ^- T

7 E$ Q! @% E* e, {, }    private String getPath()& x/ d" |3 ?7 G3 M& P6 ~
    {3 y4 Q7 B5 ~7 A3 ~) l6 D' N" d
        String path = null;
1 I3 x7 d6 I+ O, m, t        textAppend("-----------------------------\n");
- m9 X" `1 H3 N- A- V1 m9 S
; p+ Y7 F# h9 k) w! U
- l* K  H% q5 `5 \0 Z+ s        if (!ShellUtils.checkRootPermission())
. R, f* d; y2 T6 K! s; ~        {
7 \* C, Z4 |, g6 ]- e            textAppend("获取root权限失败,请在设置中授予权限!\n");4 n- z( o& X( j, f- B' ^- v- n* O
            return path;; r7 e# `* L+ [* g# a% b* }: b
        }% ~! X. \( E7 H4 H
0 ~) H" h8 }8 j1 t. V- Y, _
        path = ShellUtils.execCommand("pm path com.tencent.mm", true).successMsg;% v1 J" y1 l$ Q; F2 w) @* S* K
        if (path != null)
9 {* M  W. D5 }6 j! }% p5 q        {# p$ x# X1 m" a- K% k8 q) `
            try
8 L4 Z& M+ J9 ~5 n            {
& A( c: e/ C, g1 k( l                path = path.substring(path.indexOf('/'), path.lastIndexOf('/'));
$ Z" `; y8 }6 j2 k  D4 ~  `            } catch (Throwable throwable); h2 V8 T9 m6 {5 a3 S& E( A
            {+ D- p" Q/ P( Q
                path = null;
/ h2 }# W8 |" ]+ s! @2 r0 Q            }  i  ^) q# A) {# N
        }
! z* Y" z2 H/ J& e0 x) o* q/ p9 a: s. Q4 }6 Y6 \0 o  A
        if (path == null)
4 Y- j3 f. U. @        {
% x3 X6 C0 @  v5 b8 [            textAppend("未找到微信安装目录,请先安装!\n");! M+ }' a; Z5 t7 U
        } else3 `* y& q2 ?; n3 }, E
        {- L& u& N, M$ H$ u, X# R! M: @
            textAppend("找到安装目录:" + path + "\n");" G0 s4 a% _% ^  N1 h2 R1 d; v
        }
# ]1 Q6 K% k+ o, {' ?, ^% q1 O( z
4 X0 K# ~/ N6 Z. V        return path;
* x' e' i6 J3 ]3 A    }
7 x! V/ |) u4 L5 b
% M2 w% e# V- F+ h3 q  l* _    private boolean isEnpty(String string)
. z3 ~8 N5 p7 p( w    {# Y% r* [1 T7 H# \2 _
        if (string == null || string.length() == 0)) z( R- |# a1 L" y4 q: T4 G
        {/ w% O& |& d% N$ C
            return true;
! z$ j# g5 f# `; a: Q; {        }7 w, _" y; `3 K1 w/ n
        return false;
3 I. l3 U6 u! f% ~& {    }: F1 n+ H8 X$ P; f. @

5 Q0 F4 |" h7 [" w! P9 A7 v0 [' ]    private void putResult(ShellUtils.CommandResult result); S% x5 c" _) \8 \$ g$ t+ e
    {3 \& ~0 N) b( m9 U& ~9 @# Y
        textAppend("返回码:" + result.result + "\n");8 \9 B4 K1 q' X9 Z, z

$ `7 h/ ~7 N: T& |3 f! V8 A        if (!isEnpty(result.successMsg))
# B7 b1 _) W. v) _# h. z        {) \% V3 I3 h$ p: v2 ?, V+ e' k( r
            textAppend(result.successMsg + "\n");
3 x8 T5 g9 ~0 [- A        } else if (!isEnpty(result.errorMsg))
& P/ \4 N8 l9 @, g% Q: p2 B/ G9 F        {5 J' M- y3 v9 M- Y
            textAppend("错误消息:" + result.errorMsg + "\n");2 b# @4 f: O2 {
        }5 z0 y* W: _3 N& ~! E
    }
+ N4 k- d. d* }& x- O5 v- r
9 O( ^6 P, @2 C- [+ l8 D3 h5 J    @Override' F, D: z: X. N5 c% d4 q& C, e
    protected void onCreate(Bundle savedInstanceState)
$ e% f8 A) O2 b+ r# O" t+ Z    {
# v) z# t; ^, Q( _7 ]        super.onCreate(savedInstanceState);& y, F; ^3 w5 X! Y
        setContentView(R.layout.activity_main);4 C- X1 I2 a; o, Y0 q( w
        handler = new Handler();
, `, Y# k' @" d% A  G
5 ~# C  B1 ?- n0 D        textView = (TextView) findViewById(R.id.textView);
; L" ]1 S' @4 c  y) V, q/ k        textView.setMovementMethod(ScrollingMovementMethod.getInstance());
- s$ O1 p$ q" l+ c3 m/ E2 i5 d8 f1 v# U. B4 p
        ((Button) findViewById(R.id.button1)).setOnClickListener(new View.OnClickListener()) I4 {- i% T- G' v4 ~; v4 p. }" w
        {
7 \' {+ K3 E; k! d            @Override2 Y9 L9 m! F: [" _) X" K* _
            public void onClick(View v)$ P9 S4 r" ?1 k/ K; v# B& B
            {
4 \+ o5 V3 p; \& u' r$ W7 X
- h$ _% `" W1 G) k  ], b( J& A+ d6 J                new Thread()
& N6 E9 w: M7 U+ g                {/ G( U2 c2 z( f: A
                    @Override6 u# Z; {5 L8 _% L" _
                    public void run()  \3 C  z/ a: s1 m' M
                    {
. A5 K% S3 ]* Z( @# X% N* Y; B- {1 E0 v                        String path = getPath();
7 a% \0 H& W' o                        if (path == null)) m2 Z7 w5 `6 a. B1 M
                        {
1 p. W* c8 M& |% ^4 v0 O                            return;
8 d1 ~4 y+ P5 ~3 Z                        }
+ z& ?! }, v- T6 Z" i                        textAppend("正在保存安装目录!\n");: y1 `" J  t5 S1 l6 R: y
                        ShellUtils.CommandResult result = ShellUtils.execCommand("cp -af " + path + " /data/local/tmp/com.tencent.mm", true);
" c# s; B% l/ L0 H$ D                        putResult(result);, m4 F7 `1 D, j. F+ D2 {: V
                        if (!isEnpty(result.errorMsg))& x3 P' M8 o$ x' V! x$ W4 Z; o
                        {" G4 @- k2 o5 \9 M' L$ B0 F
                            return;
( V- q, h6 z2 R. t* R                        }, E: C  _  y$ n
, a" |3 s/ Z7 c9 F! G
                        textAppend("正在卸载微信!\n");3 J( R. A; a# d. K' j. w
                        result = ShellUtils.execCommand("pm uninstall com.tencent.mm", true);//-k无用
- ]4 T& b5 d  u4 M1 P, C. t                        putResult(result);( Y  d4 I7 @& m9 r& S; P, ^* L
                        if (!isEnpty(result.errorMsg))
, I' M, X6 C) ~! ]9 Q2 g  U                        {$ T1 r* L* Q- C; ~( v
                            return;9 n% U( l0 @, v* S* m: y7 X
                        }6 O) d' Q) H$ x% [5 m2 c: B

0 J! H8 g1 U+ p. C# @+ ~                        textAppend("请安装新版微信,并在登录成功后点击【覆盖安装文件并重启】按钮!\n");. p! d5 f3 T1 D% z1 z0 B. M. ?: o  {
                    }( G7 R5 P6 ]& ?, [
                }.start();
( V. e5 X) |) ?+ _) Y! J
4 A6 L& U  l4 q            }
6 C, i. p6 L7 z0 f        });+ B+ |1 X, f$ {+ V+ h
5 ?" i- W9 J# Z& O" o2 X4 z

0 T& t7 I7 l" K* P, s        ((Button) findViewById(R.id.button2)).setOnClickListener(new View.OnClickListener()
! U/ X, C& n5 P- _        {
, H2 S1 g6 X: T7 w            @Override
3 _: f0 ^/ r4 n+ s1 ]            public void onClick(View v)
8 f2 _3 V5 G- L& m, G3 U& n            {" {) v# x6 T8 F) }8 k, f

( r! b5 l, u* U% }# r+ T                new Thread(): T* o2 g, S+ ^6 h& {- l9 E
                {! B8 Q( M2 ~( A' P  O: Q! `4 }
                    @Override* W: h' t) u* ^/ K* p/ }( B
                    public void run()
1 @! a8 {, U0 O( ?                    {7 L/ o8 K6 A9 Y4 y
                        String path = getPath();
  Q6 v1 ?. Y# ]- H7 b                        if (path == null)
( A" y5 t, j# f9 z& v: U                        {
8 o7 {% K3 p; h6 ], ~$ L                            return;5 T- B4 j2 m$ i
                        }: M( z3 K& v% @; |4 W$ k

. ?/ Q& j7 i$ `( q+ T, y                        textAppend("正在检查是否有备份的安装文件!\n");
$ x7 M5 C+ b3 t9 d( A. R5 t+ H                        if (!new File("/data/local/tmp/com.tencent.mm").exists())
# ~6 o. r! e' M1 }8 B( M                        {' ]# Z- X2 [* H" l$ {) i& O
                            textAppend("不存在备份的安装文件,请先安装低版本微信后点击【覆盖安装文件并重启】按钮!\n");: E/ p. c% X1 h* [. l% e
                            return;& ]+ y5 A) Y- m7 y4 `( U' Z' Z
                        }
& C- I% r! W& o" `
5 j1 s7 Q) [; I2 _; }1 y                        textAppend("已有备份的安装文件,正在删除当前的安装目录!\n");" _2 F( ]# o9 C1 v/ t" k
                        ShellUtils.CommandResult result = ShellUtils.execCommand("rm -rf " + path + "/*", true);
. n# Z1 N( q, }, q2 S3 {                        putResult(result);& E0 `" ]7 ^2 ?0 {5 A! k! p
                        if (!isEnpty(result.errorMsg))& v9 ]1 u" j, h. h, @! X
                        {! m6 ]# _( x  `. H: \, S
                            return;
2 O2 u5 U( A6 f                        }7 v. ~/ Z9 t5 ], L2 O

4 ~( i, N; K' v# F, s+ B" q0 J
" _) W  ]  C* p( A- J0 b' {& O                        textAppend("正在覆盖安装目录!\n");. M; t% J4 E- q$ E9 d
                        result = ShellUtils.execCommand("cp -af /data/local/tmp/com.tencent.mm/* " + path, true);
) j3 C- ^0 Y" z7 A- ~; Y6 W                        ShellUtils.execCommand("rm -rf /data/local/tmp/com.tencent.mm", true);3 Y2 x$ R7 N" b  q+ g
                        putResult(result);
5 D8 R$ w- b0 j: A& v* N                        if (!isEnpty(result.errorMsg))
. I) Z' Y0 o, T0 f% Y( \5 ?                        {- O$ i  N- E$ d' m$ M
                            return;
% }" [/ D/ U4 H  _* z; a                        }
. R; S/ @5 g. Z0 E0 d
# w/ Y( H! t& o" Y9 x1 M8 U& ^* A" t                        textAppend("系统将在10秒后重启!\n");
% g0 F! u  i1 j/ {  h3 P6 L
8 x, a4 f/ ?- o% V$ ~6 b: \) r
0 h1 ^$ ?* K2 y1 _% x  v0 r, ?$ ]                        try1 \9 }/ h9 A1 g6 r* P  R% f( d
                        {1 a1 V8 d0 |1 ?6 w( Y' w
                            sleep(10 * 1000);
  J4 k  W+ {7 g: o4 T                            handler.post(new Runnable()
9 T  f, z8 J7 K                            {% o6 U/ {  N, \& e& ^+ `% J  N
                                @Override
0 F+ C% R: N  e6 k& \+ t                                public void run()
5 P5 h( P; Y$ u" E  Q; L4 O                                {
& e  o9 j" K6 j( h  T, ?                                    ShellUtils.execCommand("reboot", true);
0 X( W1 k2 k/ S, A$ p                                }
" L" E0 z$ u5 i1 A4 h                            });
' }0 }: W# C3 h1 S- J1 O                        } catch (InterruptedException e)
6 n" r: K7 s4 Q, @% w3 t                        {8 M- M4 I# N( r& N, Z
                            e.printStackTrace();/ T# q) R9 ~5 ^6 O* l
                        }
( s2 e$ v/ S! a$ P                    }' w/ A8 t6 e9 p. \  k' m3 S
                }.start();2 q. ~' t) a  N$ Q2 Z' \7 W, c
; Y# `, F; v& o& O3 ]
            }
" y: q, G9 b# y" v7 A2 X+ x        });) I# G3 u" s( x/ K8 `; \
& X& J6 ^0 M1 T6 \
        textView.append("-----------------------------\n");6 D1 A4 a/ z, K+ |6 G( ~
        textView.append("该应用需要root权限!\n");
1 R+ Y# Q5 T  w1 l        if (ShellUtils.checkRootPermission())* h( t+ f( T5 x! ]
        {
; ^$ P) p# C( |+ i. \2 N: _0 K, h            textView.append("获取root权限成功!\n");2 _: w  P. ~; ?( L5 x0 r
        } else
# h) L) Y% b3 \% }; g6 \        {
# w1 Z" p3 k6 E; k/ b# }            textView.append("获取root权限失败,请在设置中授予权限!\n");" `- V9 O* }3 C  Y/ _
        }
6 T) d2 d2 G9 R& J# V) [1 }1 _' c- `; \

, j. ~1 @' @6 k8 `    }
5 \* y9 i% S! K) D5 x}[url=][/url], ?$ z' u) I1 |. Y' e

+ w. s3 ]7 t% _, y% \; [- f6 D
1 A( `  \0 ?! _- z1 B& H
运行如下:
先安装旧版本微信,
运行该程序,点击左边的【保存安装文件并卸载】按钮,
  安装新版本微信并登录,
  点击右边的【覆盖安装文件并重启】按钮,
  重启后重新输密码登录即可。

5 j( i& X6 K8 U7 {8 R) n; A- q5 c
完整代码 wxreversion.rar
安装包在release目录中

2 l" Q( e6 R( u4 l# T, f
转自:https://www.cnblogs.com/JOUO4/p/9976939.html





欢迎光临 下沙论坛 (http://bbs.xiasha.cn/) Powered by Discuz! X3.3