下沙论坛

 找回密码
 注册论坛(EC通行证)

用新浪微博连接

一步搞定

QQ登录

QQ登录

下沙大学生网群8 QQ群号:6490324 ,验证:下沙大学生网。
用手机发布本地信息严禁群发,各种宣传贴请发表在下沙信息版块有问必答,欢迎提问 提升会员等级,助你宣传
新会员必读 大学生的论坛下沙新生必读下沙币获得方法及使用
查看: 8172|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    14 小时前
  • 签到天数: 1444 天

    [LV.10]以坛为家III

    发表于 2019-12-17 09:43:25 | 显示全部楼层 |阅读模式
    设备要求
      已root的Android手机。
      注:下面使用的两个微信安装包,com.tencent.mm.apk为旧版本6.5.16,weixin_new.apk为新版本6.7.3
    背景
      最近在弄一些关于微信的东西,测试过程中,本来打算强行停止后重新启动微信,结果手残点到卸载了。当我重新安装后出现了尴尬的情况,登录的时候,提示微信版本过低,需要安装最新版才能登录。
      
    " V# h9 ?" X: C+ C
      但是之前做的一些东西都是基于老版本的微信,所以不能安装新版本,必须想办法在老版本登录才行。

    * a  h  U+ `) j/ N3 D操作过程尝试1、替换版本号
      最开始的想法是,既然要验证版本,那我就把旧版本的伪装一下,让它变成新版本的试试。
      但是,因为没有时间去仔细分析微信是怎么验证的,于是就抱着侥幸心理,写了个xposed模块替换版本号,
      一般情况下是通过以下代码获取版本号的:
    PackageInfo packageInfo = getPackageManager().getPackageInfo("com.tencent.mm",0);int versionCode = packageInfo.versionCode;String versionName = packageInfo.versionName;' ~# j$ r# J7 @( U. s1 V: A
      所以去hook getPackageInfo方法,将其返回的PackageInfo中的versionCode和versionName替换成新版本的值就行,
      但是,由下图可知PackageManager是一个抽象接口,
      所以不能直接hook它的getPackageInfo方法,要先获取getPackageManager返回的对象的真实类型,先随便创建一个工程,通过以下代码获取真实的PackageManager类型,
    Log.v("test", getPackageManager().getClass().toString());$ d/ i( \, z0 p* H
    . j9 c  a' v8 r8 A& m5 n+ F
    查看日志,可知真实类型为android.app.ApplicationPackageManager,
      然后通过反编译最新版本的微信,获得versionCode和versionName,
      最后的hook代码如下:
    [url=][/url]
    3 p( h8 b. N$ E# N: j, _7 F8 Kif (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]/ k: p" X0 [$ x* h( C
    9 y) d4 c& r# v( Z
    : d% ^. E; v  F* G/ r
      编译安装后重启,一边输入帐号密码,一边祈祷,结果还是提示版本过低,

    * [9 M( d+ l* J' w7 O尝试2、pm uninstall -k 命令
      想着之前旧版本的都能正常使用,说明只要有登录数据,就可以使用旧版本的,所以想着先用新版本的把帐号登录,然后使用 pm uninstall -k 命令,卸载应用但保留数据,然后安装旧版本的。
      先安装一个新版本的微信,
      登录帐号,

    3 R/ \, |. p/ r: b! e
      使用pm uninstall -k com.tencent.mm卸载后安装旧版本的微信,
      结果打开还是不行,还是提示版本过低,

    8 J( r9 I; A1 W2 W) C
      于是怀疑卸载的时候数据被一起删了,根本就没有保留,再次执行pm uninstall -k com.tencent.mm,查看data目录,微信的目录已经不存在了。
    尝试3、adb install -r 命令
      同样先用新版本的把帐号登录,然后使用 adb install -r 命令强制安装,结果还是不行,不能安装比当前版本低的,,,

    * {" p9 [7 \0 `尝试4、替换安装目录
      既然用 pm uninstall -k 卸载时保留数据不行,那么就尝试手动替换。
      首先安装低版本的微信,把安装目录复制一份,然后卸载。
      再安装新版本的微信,并登录帐号。
      用之前保存的旧版本安装目录替换新版本的安装目录,然后重启手机。
      重启后提示登录错误,重新输入密码即可,
      不知道为什么,这个手机在我写这篇博文的时候,关于微信的页面还是新版本的版本号,而我之前弄的另一个手机就是真实的旧版本号,
      但是这个手机系统设置中微信的版本号已经变成旧版本的了,也不影响使用。
      另一个手机的,
    $ _. j8 k3 r) H+ b3 }
    自动化程序
      把之前替换的过程写了个自动替换的程序,代码如下,其中使用的ShellUtils在之前的一篇【Android手机插上usb能充电但不能识别的一种解决方法】能找到:
    [url=][/url]( k& s! _! y6 O2 U  Z
    package com.example.wxreversion;
    & t5 f8 i, j* p) `2 J3 x  s6 }0 X! ^
    & X! O7 s- z2 r1 @. u; S/ timport android.os.Handler;0 u! A$ r: L6 h% s7 m
    import android.support.v7.app.AppCompatActivity;! T! Z$ t3 L# z6 H
    import android.os.Bundle;
    # ~2 l5 |1 r1 b; a+ Uimport android.text.method.ScrollingMovementMethod;
    $ T# D. ^# A, U7 K8 M+ Timport android.util.Log;: G, ^. Q& m3 J0 F$ l! e# E) {% h$ U
    import android.view.View;
    1 S" n- y: M/ T' a$ Fimport android.widget.Button;& e: E7 K- Q0 @" B8 d( B
    import android.widget.TextView;0 D+ \$ \8 ^$ _/ }9 y  |
    8 v; ^4 @9 L3 x" }" k
    import java.io.File;
    + G3 W) _9 C) L! g
    + N3 `8 w5 |+ i/ @7 u" S& D- Jpublic class MainActivity extends AppCompatActivity
    ; ?/ ?$ ^& q! w# v# Z{
      p7 R5 u+ y. q    Handler handler;
    , O# C4 l, g' R; s( o. h+ }    TextView textView;# U; }$ Q4 x" N0 Y4 \& c$ q8 ~5 {9 f
    - v+ t& d( k- |- Y4 k

    % _( p% P7 L( q    private void LogV(String s)% q& S/ Y) Z2 Y8 F
        {) V/ b; m" E, F5 ~& k
            Log.v("test", s);
    8 j" e* N% s% R    }* I. S. R( X& m$ N

    1 l, f% W  h! t* {    private void textAppend(final String s)
    % |; \$ x' K: L4 u5 J    {
    / [7 a2 _+ x- S4 {% k( o) |) P# n        LogV("textAppend:" + s);7 C" V, W, x5 N! A8 H. y7 u" c9 a
            handler.post(new Runnable()
    / ?# a5 o5 c) m$ a  s) d        {
    3 N: Z& n- a! b3 |; o2 r            @Override: [, d/ }% ^' |5 `5 S1 s6 J
                public void run()% U+ ]. g% Z3 k8 ?7 Z
                {
    7 N. M" J% Z: A                LogV("run:" + s);3 a; p; O" v* x: H% N" `) X
    1 Z0 G% W8 N, ~! z3 V
                    textView.setText(textView.getText() + s);* Q0 x" Q. R; x! o1 ]5 Y: u; ?
                }
    4 e; J+ @0 ?5 z5 T( ^+ v6 ~* E        });$ Z/ d! e: d- z2 O+ z! _9 D
        }
    : r+ S# i2 p) O" Y/ O- W8 h( p1 y( L! i4 C+ b/ {, V# L
        private String getPath()& K1 x& X$ b  J4 `, K
        {/ a  l5 r, c  J  Z0 i% ^# Q
            String path = null;% u! a# N1 V% u
            textAppend("-----------------------------\n");
    ) Q. P$ v- b# z, X5 e, j$ ~2 U/ S
    - r. S: {( B  b8 I$ N; N- j- o0 c. H0 j4 `
            if (!ShellUtils.checkRootPermission())4 l8 B3 }# U5 q% z" m/ f7 `
            {1 o! w* Q  r' ^* q
                textAppend("获取root权限失败,请在设置中授予权限!\n");
    ( \% @7 A' R3 `            return path;- L! G. s7 I. `5 i) C6 f' S) ?
            }
    $ v9 p% @  z/ s! n
    4 m$ |! h. G+ j+ H2 s7 ?9 G        path = ShellUtils.execCommand("pm path com.tencent.mm", true).successMsg;0 E. E! z& S6 Q& H! ?- r( {) H
            if (path != null)- G0 t, V8 [7 a/ @# q
            {
    , e% y6 Q, l( l2 g            try
    " M$ D& ~) F9 b7 o2 l            {
    ! ^! c( b( Z+ Z                path = path.substring(path.indexOf('/'), path.lastIndexOf('/'));# ~! O7 r4 j7 m
                } catch (Throwable throwable)0 K4 s8 T' S4 P' j  q0 D
                {( G( E6 ]. F# z- u) E6 V. q
                    path = null;
    ) z7 o! b: }7 W4 Z            }, v( `! _# W! t) G& k
            }
    & _1 E; n" p! |% h/ @4 d, F: M8 ^4 r6 f# i  P
            if (path == null)
    6 b) j/ ]7 W4 t6 ?- v6 T; y        {
    ( m( L; t2 t# V* B/ V2 a            textAppend("未找到微信安装目录,请先安装!\n");
    $ m' P( O1 O8 ?( e7 C        } else  p3 e: _/ Z! V) Z9 O; ^% Z8 S
            {) N( Y; }0 G% [1 R, X
                textAppend("找到安装目录:" + path + "\n");: U8 |0 I4 q' D8 Y
            }7 ]! i  e# S3 S; ~* M" M* w
    # s1 [) z4 ~* R( V# q$ r
            return path;
    * q9 X' I1 v" B    }
      O- d) Z- O9 d% T9 q% S: O% \' ]" A; S+ A+ x- Z# r% h
        private boolean isEnpty(String string)
    6 Z$ U/ B' o+ k" L; J# l    {# j+ R/ W; H  X
            if (string == null || string.length() == 0). L5 Q4 f3 d$ l4 n# J) m
            {% u, j1 V2 ~" _+ O( ~6 q
                return true;
    . {* i: q# g2 k% F4 E9 Q  a$ @        }
    # V% z( x- n8 _% F/ p6 u        return false;
    3 a, B; g* I4 a% p! A5 ^) q    }: W/ O: j* f2 p# S" t  x
    / s' K( @: H! M' x& N! v( e
        private void putResult(ShellUtils.CommandResult result)
    8 {# G& y, g+ v9 ?+ W7 n    {" c+ a# k8 l2 a4 z& h6 p2 C
            textAppend("返回码:" + result.result + "\n");
    1 I5 \# V+ x3 k8 y: R1 r' {
    & {) [. y: g' g1 r. I4 s3 D        if (!isEnpty(result.successMsg))" g) r2 _  N; C( ]! F7 D6 h
            {
    4 `- J- S0 c6 [  `& I7 \: Q/ E            textAppend(result.successMsg + "\n");
    * Q% |, i) F  R9 q9 C  @        } else if (!isEnpty(result.errorMsg))
    ' z4 d6 m5 l1 q6 L- c9 X8 c        {+ H2 @& a" W& k$ b" w8 H
                textAppend("错误消息:" + result.errorMsg + "\n");( ?4 {$ y, C1 O
            }
    $ d1 s' |$ e3 o, E# E. [    }
    " _) L/ N; s) z  L0 ^" ^2 O- O4 s
    1 g! w8 V2 }' h4 \* D    @Override% y" u7 [% ~$ d7 P) x$ t6 @
        protected void onCreate(Bundle savedInstanceState)  m* a. a# e& b6 H
        {7 g+ G: ^" U5 A0 |6 o
            super.onCreate(savedInstanceState);% C. V* f0 W. o6 N$ z2 O
            setContentView(R.layout.activity_main);
      ?: L7 v# m! Y, I( C) }; Q7 `" [        handler = new Handler();$ Z# z# E- Y! o+ n) P! [& _- v$ y

    6 i, R. U, x# ?  p5 K6 M# p" ?        textView = (TextView) findViewById(R.id.textView);
    ' O; t9 r: C+ W6 T& ^) _4 W        textView.setMovementMethod(ScrollingMovementMethod.getInstance());8 X8 f# q+ a: g
    , v( y' C+ b2 N0 u  F* N
            ((Button) findViewById(R.id.button1)).setOnClickListener(new View.OnClickListener()( n( Z# ^) X4 A, ]& h& A# w
            {6 ]8 g. C' r. A2 g
                @Override* l4 q6 D& O* Y* |& Z5 E7 R: R
                public void onClick(View v)
    9 M, \4 X3 t& V9 i1 u; z- g9 T2 c            {
    6 k5 }# A8 g6 X
    7 L( `: F) \) W) f/ H                new Thread()
    $ A2 W) y3 d# s                {* C$ \2 B6 h; R1 b5 T$ j3 f
                        @Override# F- \, F1 y/ l- A% D, p* p' v5 ~
                        public void run()
    0 K; G  ?2 G8 P! c                    {( ~& \6 t( t8 ^1 R1 b7 c* F  U
                            String path = getPath();
    1 l; N5 w9 M/ f7 L( T: |0 x                        if (path == null)7 t2 R2 M* {# i$ ^" I8 G: v
                            {5 E# j! \; r. A3 W, _
                                return;: x7 T8 g- P# B) b$ V& }5 c
                            }
    . u1 [# m* M9 j7 K7 v8 F" l1 R                        textAppend("正在保存安装目录!\n");
    9 {3 y9 `9 M& a8 c# y8 ~                        ShellUtils.CommandResult result = ShellUtils.execCommand("cp -af " + path + " /data/local/tmp/com.tencent.mm", true);9 y1 |& ~/ x4 ]8 r' d$ z# o( ]/ p
                            putResult(result);
    : m- D  a" C! R! K- ?( {; u                        if (!isEnpty(result.errorMsg))1 k( m* }8 L' S
                            {
    - K3 k* k- E$ G! H) ~8 o+ }                            return;1 K" G: a; Q/ y6 l6 N2 n  N
                            }2 F9 @0 x& s, k
    * E/ n. g  z# y/ g
                            textAppend("正在卸载微信!\n");
    ( Z% U2 W. z) i  r5 k                        result = ShellUtils.execCommand("pm uninstall com.tencent.mm", true);//-k无用
    8 s+ }+ X  [6 C5 G2 S& w                        putResult(result);1 c: U6 H) i# m$ r0 t
                            if (!isEnpty(result.errorMsg))1 H8 n+ J) D, y" l4 p( P: M3 ?
                            {% P* x5 V. P9 x1 a4 i/ D- x2 j
                                return;9 i5 Q. ~5 ?  V1 v9 r, b8 T
                            }
    8 H9 b$ ^4 i% E/ N3 E$ y5 D% V& y; ~: P! N1 ^+ L
                            textAppend("请安装新版微信,并在登录成功后点击【覆盖安装文件并重启】按钮!\n");' I- m4 Y, A9 ?/ D
                        }3 |5 k" ^& Q/ c* b$ Q) ?
                    }.start();9 G, U) I  \1 H0 U7 @. A- Q
    $ q" a  M) Q7 {6 Q' Y7 R
                }
    3 b. |. ^- W& P( ^4 S+ w# i) P9 I        });) E; N, d2 s0 |6 B5 _- j

    , m4 C/ a# h/ P9 Y% _9 j- }5 m$ U
    % T, L- D1 M" G        ((Button) findViewById(R.id.button2)).setOnClickListener(new View.OnClickListener()
    $ }/ k$ p- P& p! h8 o' X* x' G! m( s        {
    5 d7 e1 T0 J# b+ O. M0 L: C. w3 J            @Override* v& C4 V2 y# C& y3 M+ i8 \
                public void onClick(View v)- u- n( b* `" i
                {3 k2 o5 T$ G: \8 v! Y. Q% q) r
    + y! \1 N7 t3 w
                    new Thread()
    / _( `2 l3 S; D" h                {
    4 x! d. Q, @+ s  U+ [- w% f                    @Override/ `0 {( j3 N/ `2 F0 U5 G
                        public void run()0 y( u" n( y% a, n
                        {0 o' S- D# o3 R# G5 r
                            String path = getPath();" k7 d6 e6 Q8 [1 l0 I& o
                            if (path == null)% V1 y( |" w; R) r! R
                            {
    0 X6 N) I1 s4 f; d" M                            return;
    " O% E3 q9 J# Z$ m# B% @                        }
    , ^) u2 n9 ~! T1 S, ]2 p- r8 T4 @! f( a2 c
                            textAppend("正在检查是否有备份的安装文件!\n");
    4 d, w5 {( P. ?# t) O                        if (!new File("/data/local/tmp/com.tencent.mm").exists())
    # T( m' l' _/ |, E* Z                        {
    ! \" A' Z1 ?; u                            textAppend("不存在备份的安装文件,请先安装低版本微信后点击【覆盖安装文件并重启】按钮!\n");5 P, h2 i- t; e5 h* `4 @8 b
                                return;- o5 L  v, t+ |$ o# W( e
                            }0 q, r6 y& A  g, ?  n% P

    " e+ W3 t+ m. Z) b9 t# [                        textAppend("已有备份的安装文件,正在删除当前的安装目录!\n");5 N  Z7 G* ~* h3 F3 e9 f& L' E
                            ShellUtils.CommandResult result = ShellUtils.execCommand("rm -rf " + path + "/*", true);
    4 E2 f& k" ]8 h) i- U( L                        putResult(result);9 M; ^( a: Z7 W  t7 u+ X
                            if (!isEnpty(result.errorMsg))
    2 ^' g9 _- j! l/ J. z6 c9 `0 c                        {& ^2 D% [2 g# k  F2 m9 L
                                return;9 E/ C- k7 r4 ?% e- E
                            }& t1 Y- s* b! N' z. w: G

    / Y# }) G& Y0 f" ]0 G/ x3 H' ?( R4 ^: e" N% s% P
                            textAppend("正在覆盖安装目录!\n");
    ( {4 H( `0 `8 z* v                        result = ShellUtils.execCommand("cp -af /data/local/tmp/com.tencent.mm/* " + path, true);
    / N; O/ ~" t. M, s( G                        ShellUtils.execCommand("rm -rf /data/local/tmp/com.tencent.mm", true);* [& l1 P) ~( _$ q
                            putResult(result);3 w1 n% E* e  t# F. J
                            if (!isEnpty(result.errorMsg))
    ' W. j8 j8 x5 W0 z                        {( E# w, n' }, |5 ^
                                return;( `4 \' I$ o* F* K; R( c
                            }
      V; A3 }; P3 w% g% c2 a3 _
    , I* ]2 j' }8 i) k' i; i- I                        textAppend("系统将在10秒后重启!\n");
    ) }: |' {; V8 C2 J; P% T+ b
    + v2 }' i, Z" h7 h: G( w2 n0 @0 }" h' K  o* l4 _
                            try
    ' `2 A' c. p  ]8 n' J                        {" V6 N/ ~! }9 r
                                sleep(10 * 1000);
    / n$ i6 h# F, H1 m                            handler.post(new Runnable()4 F2 q" b& {% J# ~/ I5 _% w7 n4 U
                                {. T9 U' J2 s% d3 R
                                    @Override
    ) N' V; x6 }9 `9 |                                public void run()' A$ k3 ~$ M+ P5 l* ]- F2 s$ E& m
                                    {. k2 j; K7 J* f) k; q7 o
                                        ShellUtils.execCommand("reboot", true);! P7 X* ~/ @2 o: z
                                    }
    * c. U9 U7 Z( G2 R9 y/ C                            });
    1 _) N; z$ c7 U                        } catch (InterruptedException e)/ _: S1 d, p7 U  G& ]. ~
                            {
    * p" U7 n3 z) i+ A! ~                            e.printStackTrace();
    0 [) k! w0 q& v( }                        }5 n2 n: _+ v0 T3 e* g7 g
                        }% s7 q7 Y, J2 `/ m7 B
                    }.start();
    , J, T# e9 Q. v7 \; G. T3 x4 U+ e; i& Z/ S
                }
    ) N4 v5 [! a6 l& x* K/ P        });/ p; K8 [4 U4 s5 r- u9 D

    6 ?  k/ D7 P. `5 H        textView.append("-----------------------------\n");2 U2 J8 G" t5 ?7 ]7 k" v
            textView.append("该应用需要root权限!\n");
    : ^3 n% i/ R  \) k        if (ShellUtils.checkRootPermission())
    3 e+ H" M' x; a  z& F5 E; {1 W. A        {( d! w) T6 X5 T1 `! E- f$ l
                textView.append("获取root权限成功!\n");; t$ m" q% }0 z2 X
            } else$ ]* ], D( |& ]% y9 j- @* Y, y  `" }
            {
    ; X8 J! p; n9 J* I( b- ^            textView.append("获取root权限失败,请在设置中授予权限!\n");5 R% _# h1 \& w
            }8 j2 p5 @4 [% t4 B  J

    1 {& M  G( E: a  N3 d6 l" G
    1 Y* C+ e6 A5 t) Z% Z    }8 {- a1 U4 s, {" H& t. U$ K
    }[url=][/url]
    6 C' d& ~! z4 N' L# ?
    + k; V* d* ]0 R2 y' d

    2 h0 t5 z+ @( ^
    运行如下:
    先安装旧版本微信,
    运行该程序,点击左边的【保存安装文件并卸载】按钮,
      安装新版本微信并登录,
      点击右边的【覆盖安装文件并重启】按钮,
    62.png
      重启后重新输密码登录即可。
    " {' ~* J" F5 k/ X
    完整代码 wxreversion.rar
    安装包在release目录中

    $ A  ^$ [0 k- R( V1 I1 m6 V

    本版积分规则

    关闭

    下沙大学生网推荐上一条 /1 下一条

    快速回复 返回顶部 返回列表