下沙论坛

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

QQ登录

QQ登录

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

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

[复制链接]
  • TA的每日心情
    擦汗
    前天 08:38
  • 签到天数: 2382 天

    [LV.Master]伴坛终老

    跳转到指定楼层
    1
    发表于 2019-12-17 09:43:25 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
    设备要求
      已root的Android手机。
      注:下面使用的两个微信安装包,com.tencent.mm.apk为旧版本6.5.16,weixin_new.apk为新版本6.7.3
    背景
      最近在弄一些关于微信的东西,测试过程中,本来打算强行停止后重新启动微信,结果手残点到卸载了。当我重新安装后出现了尴尬的情况,登录的时候,提示微信版本过低,需要安装最新版才能登录。
      
    $ k8 k  x# K- F
      但是之前做的一些东西都是基于老版本的微信,所以不能安装新版本,必须想办法在老版本登录才行。
    ( k8 F* ^, q/ A$ f: q
    操作过程尝试1、替换版本号
      最开始的想法是,既然要验证版本,那我就把旧版本的伪装一下,让它变成新版本的试试。
      但是,因为没有时间去仔细分析微信是怎么验证的,于是就抱着侥幸心理,写了个xposed模块替换版本号,
      一般情况下是通过以下代码获取版本号的:
    PackageInfo packageInfo = getPackageManager().getPackageInfo("com.tencent.mm",0);int versionCode = packageInfo.versionCode;String versionName = packageInfo.versionName;
    , T3 n  p6 M) Y$ B8 I" ^
      所以去hook getPackageInfo方法,将其返回的PackageInfo中的versionCode和versionName替换成新版本的值就行,
      但是,由下图可知PackageManager是一个抽象接口,
      所以不能直接hook它的getPackageInfo方法,要先获取getPackageManager返回的对象的真实类型,先随便创建一个工程,通过以下代码获取真实的PackageManager类型,
    Log.v("test", getPackageManager().getClass().toString());
    8 B7 A4 i* _* l& p* q+ R7 u0 C
    7 H, o/ M3 _# _( n  H0 \& G查看日志,可知真实类型为android.app.ApplicationPackageManager,
      然后通过反编译最新版本的微信,获得versionCode和versionName,
      最后的hook代码如下:
    [url=][/url]
    ) Y- E& G" q- N( c- Bif (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]
    8 R" r) |& `2 k

    : p" [% j! B2 Q4 u
    : Z( Q" b" E) O8 @; Y
      编译安装后重启,一边输入帐号密码,一边祈祷,结果还是提示版本过低,
    + S+ j- H. Z9 E$ e0 x7 i
    尝试2、pm uninstall -k 命令
      想着之前旧版本的都能正常使用,说明只要有登录数据,就可以使用旧版本的,所以想着先用新版本的把帐号登录,然后使用 pm uninstall -k 命令,卸载应用但保留数据,然后安装旧版本的。
      先安装一个新版本的微信,
      登录帐号,
    ! h& ]' ^/ @3 Z3 C, j6 q
      使用pm uninstall -k com.tencent.mm卸载后安装旧版本的微信,
      结果打开还是不行,还是提示版本过低,
    $ H! h4 u" y9 B
      于是怀疑卸载的时候数据被一起删了,根本就没有保留,再次执行pm uninstall -k com.tencent.mm,查看data目录,微信的目录已经不存在了。
    尝试3、adb install -r 命令
      同样先用新版本的把帐号登录,然后使用 adb install -r 命令强制安装,结果还是不行,不能安装比当前版本低的,,,

    : [' @. i! [1 f7 W0 f( }. A尝试4、替换安装目录
      既然用 pm uninstall -k 卸载时保留数据不行,那么就尝试手动替换。
      首先安装低版本的微信,把安装目录复制一份,然后卸载。
      再安装新版本的微信,并登录帐号。
      用之前保存的旧版本安装目录替换新版本的安装目录,然后重启手机。
      重启后提示登录错误,重新输入密码即可,
      不知道为什么,这个手机在我写这篇博文的时候,关于微信的页面还是新版本的版本号,而我之前弄的另一个手机就是真实的旧版本号,
      但是这个手机系统设置中微信的版本号已经变成旧版本的了,也不影响使用。
      另一个手机的,
    ) z4 F( g) p$ G+ v* U# e
    自动化程序
      把之前替换的过程写了个自动替换的程序,代码如下,其中使用的ShellUtils在之前的一篇【Android手机插上usb能充电但不能识别的一种解决方法】能找到:
    [url=][/url]- H7 m. a1 E0 M/ V8 P# G
    package com.example.wxreversion;
    / R% G: S1 `1 h8 A
    ) L: U/ J5 L: g  [& {0 W& n: Dimport android.os.Handler;
    6 z8 G' J4 Q" D% r8 kimport android.support.v7.app.AppCompatActivity;/ P: E3 V$ q' S7 k  B. O8 R3 h
    import android.os.Bundle;
    7 `  n& D7 L" i. A/ f+ limport android.text.method.ScrollingMovementMethod;* X, E! `' L( n. j  x" n
    import android.util.Log;3 b6 R* W  U1 c! S
    import android.view.View;
    $ H, }0 x/ i0 T1 d+ w8 j. Qimport android.widget.Button;
    . P, u6 p8 S' O, F  t5 Fimport android.widget.TextView;! m' ]; C. `0 ?3 \0 w0 y. ~1 d

    : E* ~; l( k" ?, |5 Limport java.io.File;0 \# H9 B1 ]2 A, U

    : _! ?& {* Y$ h% v5 Jpublic class MainActivity extends AppCompatActivity
    * v6 N. D( N) `1 k{/ `6 d' q! M. @/ l! }1 ^
        Handler handler;
    5 j- u5 _( d; x    TextView textView;
    $ J* M3 m1 [% C( w$ c! j, h8 a% g4 ~% I9 h7 _' I" e3 N
    : ]' w$ z/ L' o3 J# t  X, A* @* _
        private void LogV(String s)
    $ S/ v4 V- \3 Q1 O. U    {* {* q6 u0 u* z4 f* {, R
            Log.v("test", s);
    9 [; H( Q: `, T1 b! I7 {. D    }
    & z6 |; a  J9 v0 N' M; A- S
    + j+ L! }9 k+ o    private void textAppend(final String s)/ _: u# m* x% ]' Q( f6 M
        {
    ' k4 y# |" ~' \6 f2 v$ |+ G        LogV("textAppend:" + s);
    3 p# Z: c0 @7 x$ G        handler.post(new Runnable()$ Z' _2 L7 P! t$ a! S# u
            {- M* [4 U9 E5 P  F' V. a
                @Override( e6 q/ K* i' W$ n* S' M6 }; _
                public void run()% E' B4 L# V" N, J9 N. P' |
                {) f/ e, k7 }  [. J7 _9 I8 A
                    LogV("run:" + s);$ P# B1 I; K- J2 i

    / V8 N4 K# ]' ]! Z2 H                textView.setText(textView.getText() + s);2 C# i) C# k+ @+ |8 g6 ^
                }
    $ i$ Y! R3 T/ O5 z: T; S$ ]        });2 Z, ?! \( b% h1 h7 s/ w8 x7 ]( N
        }
    / j6 O! R% V8 L# G0 }0 I& w5 O% q; s9 _" V7 b2 X4 [/ i
        private String getPath()3 Z# s; `0 @( A( {$ M/ l
        {5 e' S& W" X. e( {: J
            String path = null;0 m( ?3 N% V% u% `
            textAppend("-----------------------------\n");8 P3 B( h* o& ^3 s' ^. H

    # B/ {3 q7 w+ d5 t7 O# |' c  S
    7 M  e- \5 y4 L: B: E# a        if (!ShellUtils.checkRootPermission())
    * U3 E8 H- O& y- S: e7 K6 F        {
    * r. p. k3 |. T" ^# b            textAppend("获取root权限失败,请在设置中授予权限!\n");
    + C$ i3 M7 l4 E# i4 Y3 p            return path;
    1 Z) o5 q) ]8 ?! m        }) \/ a2 d. p; _3 f

    7 p' C* ^: d3 |! U. I/ g1 \        path = ShellUtils.execCommand("pm path com.tencent.mm", true).successMsg;/ Y$ ^- \$ _4 {
            if (path != null)
    . R. P2 C4 |1 e' A) `        {
    ( y2 X& K+ L3 y8 `( }7 m& b            try
    - S9 n5 {! w& @0 k6 _            {
    8 y$ P1 z8 \4 w; U                path = path.substring(path.indexOf('/'), path.lastIndexOf('/'));" q) s  a. B% e( ^4 Z
                } catch (Throwable throwable)
    ' ^$ r4 z% r( G% ^# E            {
    % i/ c+ _8 T4 x5 N. e# a, d3 s2 |; X" t) k                path = null;
    " z+ u. g- j0 n            }
    6 T* ^: |4 k; L5 S" X7 y9 Y        }
    ( O5 R1 b5 r+ k" k/ K5 _) h0 J
    ! V7 t9 ^8 Y2 }" @: Q/ v        if (path == null)
    $ z7 j2 e) U. A/ h# U* S8 H' D        {
    1 |2 F) c: X: @5 o            textAppend("未找到微信安装目录,请先安装!\n");
    2 r6 D1 u. W# Q# A, |+ V        } else
    5 X1 n' i9 p7 ?$ z6 B8 ~        {
    : b; `; A& Y5 c: P# ]3 k( t; V. f            textAppend("找到安装目录:" + path + "\n");
    ; a5 N0 `2 F( \! D3 ^( Q' e  R        }
    1 n: o# x9 M5 v- M1 i+ u' n: u/ a" @
            return path;; {8 c0 u) d$ m" h0 f* p& m; b
        }% Q! M! A+ B. n4 c
    $ `# ]6 O/ }) m. I$ E4 ?3 r* I
        private boolean isEnpty(String string)3 Z2 [! b- s  |9 D  x
        {
    $ k8 o# Y0 F' w3 J2 p) _        if (string == null || string.length() == 0)2 ~/ Q) ^: j7 Z
            {/ Y, r* D; e9 V+ G, i* v9 w
                return true;
    2 E# [7 ~7 o  ?% {, @1 s% I1 c        }
    ( l  a) H* E; r2 M0 H: v        return false;
    9 q9 {+ M9 n4 I2 O- Q2 E- E& W    }
    4 P  w+ s* \" B. `: h  R! ~: k3 ?5 N6 Z% L1 b+ M7 h5 E# f
        private void putResult(ShellUtils.CommandResult result)
    - _( s+ Z: `4 F. E  h    {$ f; B0 r( A& J& `; {  j, J  u4 i
            textAppend("返回码:" + result.result + "\n");, ^4 |2 i0 O! V1 ]2 g$ J* ]7 z1 G

    " U! `* B) l; n2 U        if (!isEnpty(result.successMsg))
    0 N" o9 d3 L9 ~: ~! h        {7 x3 y) e" ^; T) u& E) R
                textAppend(result.successMsg + "\n");
    ) |) o  ?; R  Q) M/ F) X) U        } else if (!isEnpty(result.errorMsg))
    & Q" d" D/ t  o' r        {5 Q* c+ n) i, Q( H% w1 w
                textAppend("错误消息:" + result.errorMsg + "\n");9 {% G7 L, H# }( r4 G8 X0 O( p5 @) W
            }
    3 e0 W) `$ |6 M% h9 w6 n- `    }" O9 V* U5 D  y. {
    ; X& R3 L7 X% W' T( ~# \0 t
        @Override
    , A, k0 }; ^# \' |/ Q" w    protected void onCreate(Bundle savedInstanceState)' a% t7 r! ?* E! ]( {. f0 W5 U" K0 a
        {
    , y. G: b" T) Z2 e0 ?        super.onCreate(savedInstanceState);5 n+ A. v4 C  |+ C
            setContentView(R.layout.activity_main);/ \/ Y. L: ?( _# ^2 X/ r1 @
            handler = new Handler();- p. x/ X& \; A: ~
    " t( _; F$ e# P8 z4 A
            textView = (TextView) findViewById(R.id.textView);5 d7 p! K/ [  y7 G
            textView.setMovementMethod(ScrollingMovementMethod.getInstance());
    9 f8 s, j: ]- d# Q' {4 \& A0 k
    ( O4 c' }) O/ ?/ l2 o+ b) @        ((Button) findViewById(R.id.button1)).setOnClickListener(new View.OnClickListener()
    9 s! @$ S2 n( R4 p3 y% a        {% j1 I4 p7 [* R5 C# k
                @Override# o; b7 R0 o# L
                public void onClick(View v)3 U( k4 `. f, v
                {
    : }8 q' |( G6 m" o
    6 ?: _. l* P! {# Y' E$ c# a                new Thread()
    - z4 \* T  O9 T$ O7 g                {
    ! P% W  o/ d. u( j# {                    @Override
    ( p3 I  ]/ W4 q/ ]                    public void run()
    ( I. U4 t; W& i# [7 E+ h( A# }                    {
    , C. U+ `. ~8 S' q                        String path = getPath();
    : H" f; l4 _5 K* f# ~1 Y                        if (path == null)" G2 [+ {5 m7 c
                            {7 w8 }) L( U' ?4 M$ u" y3 p
                                return;
    3 o- p- V3 R1 D& g+ V, G                        }; V9 J  ~3 ?: M  X6 e8 \8 ]9 T
                            textAppend("正在保存安装目录!\n");( \+ L! w$ l! F1 }' U: y/ U
                            ShellUtils.CommandResult result = ShellUtils.execCommand("cp -af " + path + " /data/local/tmp/com.tencent.mm", true);9 [' P9 F" p8 ^7 u' H; w
                            putResult(result);
    9 z* O' x5 ?& M! `, B                        if (!isEnpty(result.errorMsg))
    8 E5 }! y" w( w( r* }( ]3 x                        {4 d7 @; ~  q4 A& w( d* b' x
                                return;2 l+ U* g* e% n2 J
                            }
    " ], T' X5 S5 n' i9 M% w1 E1 [8 w- A2 ~/ l
                            textAppend("正在卸载微信!\n");  ]2 Z, {  {( R( S
                            result = ShellUtils.execCommand("pm uninstall com.tencent.mm", true);//-k无用3 u( i3 p; r! ^1 `8 }9 [
                            putResult(result);- ]0 _, k5 m. h# v, w
                            if (!isEnpty(result.errorMsg))
    3 x* ?5 @1 e6 F9 ~$ R" v                        {
    5 \6 _2 A' O1 N7 r% j' k' `: X                            return;' l; _7 q$ W8 k0 {9 Z  T
                            }
    7 e8 ^, o" J4 K0 }5 Y9 X* I# h4 `8 W1 O
                            textAppend("请安装新版微信,并在登录成功后点击【覆盖安装文件并重启】按钮!\n");8 F0 x' c6 D% m8 G7 M) Y# ~: F* g
                        }
    1 A/ B! T: t/ j                }.start();9 ?# j7 H- }; o; ~" E9 j
    9 C8 K9 B$ d3 Z0 G3 _
                }3 {3 h3 a; ?" Q- e$ q
            });
    ( L% n4 H! }  I! N) Q/ b; {# ?
    ( U7 m8 I' X$ S. v/ t# Y1 b+ f: O( {( D5 ^! R* A- S
            ((Button) findViewById(R.id.button2)).setOnClickListener(new View.OnClickListener()
    ; E/ A4 S" c* m7 f4 R0 m        {
    3 L0 G! q% e6 s+ g: Q7 n* Y            @Override6 r$ w; o8 ]% N6 O
                public void onClick(View v)* `; w# z* g9 g' K
                {
    ; W  G# W$ m/ B7 I
    2 u( [8 ~8 N/ j- p; B                new Thread()% L  ^: d6 K* ^+ U
                    {
    / }- ?* d' Y- \# N+ _                    @Override
    : ?4 P" ^% m1 k% r/ H                    public void run()
    6 ~' M3 |$ m9 W% [6 W+ f5 u                    {; \5 m. ]- @+ h
                            String path = getPath();
    4 }4 Z- b$ c8 z- c- b7 i( M4 g& V                        if (path == null)
    3 O: q: |* w1 h6 |& c2 r                        {
    ! ]0 w. \# P* D                            return;
    $ D8 m/ r+ u! @6 @- A- V6 ~% F                        }
    5 a4 f- H0 e. \* E! f! B: {2 W+ [( G
                            textAppend("正在检查是否有备份的安装文件!\n");
    3 }$ ?& Z/ S) ?                        if (!new File("/data/local/tmp/com.tencent.mm").exists())
    , I$ b1 s: j) Q3 h                        {
      V2 r$ ?6 p5 v/ l' _4 V                            textAppend("不存在备份的安装文件,请先安装低版本微信后点击【覆盖安装文件并重启】按钮!\n");! @# r, O6 v% Q3 C% f
                                return;- A+ k0 f+ e/ ~% E
                            }7 F. \9 G0 x; v* t- ]$ B

    9 j2 q  j- e3 s' W9 }/ E; w; [                        textAppend("已有备份的安装文件,正在删除当前的安装目录!\n");
    2 B/ U& d8 s1 _& |                        ShellUtils.CommandResult result = ShellUtils.execCommand("rm -rf " + path + "/*", true);
    , O7 a. ]+ s$ K" j" b# \                        putResult(result);9 _3 d1 e6 e8 ]
                            if (!isEnpty(result.errorMsg))
    6 ^! i; q- B* `                        {, p4 }+ e" w; M( V! _
                                return;5 U3 @" \" C8 I
                            }
    9 w/ ^3 r! r0 H8 T
    2 b* d7 ]& [5 m3 n2 H6 ]0 g2 k. r) P9 Q9 G7 U8 S: E
                            textAppend("正在覆盖安装目录!\n");
    4 r/ K1 t0 I: ^% I                        result = ShellUtils.execCommand("cp -af /data/local/tmp/com.tencent.mm/* " + path, true);
    : S* v" s8 g: Q                        ShellUtils.execCommand("rm -rf /data/local/tmp/com.tencent.mm", true);2 r) a6 z# f4 ?* {. W4 T
                            putResult(result);0 j/ ~; b* U+ s
                            if (!isEnpty(result.errorMsg))- C% M4 K. @6 t0 a3 k9 l
                            {
    ( M9 v0 X9 X# C. E3 y                            return;
    7 s1 E( c( p& N- {! t# S8 P                        }3 E/ }4 r: Z4 r2 V0 v6 Z. p; M

    / D0 R3 B  d3 O                        textAppend("系统将在10秒后重启!\n");1 j# u: ^/ `3 Q3 b# |% X

    + x9 J8 V- y5 v/ x2 ^2 l0 M
    , s1 K  U% u& \; h                        try; ]) ]) Z8 e( s* o) G1 t
                            {
    : g1 D- D# H! Q; B4 J3 s                            sleep(10 * 1000);
    $ ?) w) i& D3 B                            handler.post(new Runnable(): K8 F2 d1 _4 ?/ i
                                {
    2 }; L8 W8 `3 C) _  i. L                                @Override7 P0 V; D7 ]$ C, Z
                                    public void run(); f) u0 e. ^3 P7 `/ q/ T
                                    {* {. W: e0 H5 p( ]; `7 x& M
                                        ShellUtils.execCommand("reboot", true);2 V! S: R  J0 v& {# {% h* w% l
                                    }, p9 U% R8 `7 e
                                });
    - N% q& i8 W$ W; c* h                        } catch (InterruptedException e)( v' Y% V7 l0 l; x4 }
                            {7 G9 J% E% [$ G/ T- x* W. L
                                e.printStackTrace();
    4 d3 ~2 g8 l1 }* M' r                        }! i8 S8 N# I, b2 ]8 [; K9 A, F
                        }
    . R. }9 ?6 D1 _: ^                }.start();
    8 _( z+ n  P, B, `' W9 N
    : Q5 r& M2 X! \$ N$ O, R: O# W            }* H" V7 s1 n0 x/ f0 v
            });
    - I, `4 I5 D- J! e8 S+ ^. l3 h0 r" N/ X9 E; ~7 c
            textView.append("-----------------------------\n");
    ' P0 D& A% _2 ?; r, ~: O        textView.append("该应用需要root权限!\n");
    7 n5 U9 F; Z) k5 j        if (ShellUtils.checkRootPermission())5 E0 W2 E" J% ^* N- C
            {* L/ U' F. [, ~$ U
                textView.append("获取root权限成功!\n");4 |; B: j$ R- g
            } else/ Y: u- x/ [3 H* v
            {
    . W" s1 u: O8 D! T            textView.append("获取root权限失败,请在设置中授予权限!\n");& @8 @+ _4 r- S6 B8 S
            }
    4 K- [; I0 R. P  d; V6 m+ v) P. e* V/ O* D9 h4 S2 i7 e

    2 \2 @; X0 W. Q9 |    }8 \6 W' v& |4 x& m: b" F( B- d
    }[url=][/url]0 d' u+ t2 E# k
    / C3 E1 q- |9 b

    8 a  F+ m$ o$ H% s* r
    运行如下:
    先安装旧版本微信,
    运行该程序,点击左边的【保存安装文件并卸载】按钮,
      安装新版本微信并登录,
      点击右边的【覆盖安装文件并重启】按钮,
      重启后重新输密码登录即可。

    " D$ f( x1 g8 q0 N/ x& S/ A
    完整代码 wxreversion.rar
    安装包在release目录中

    ' W: k+ x- f' d2 B+ a3 Q
    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏 分享分享 顶 踩

    本版积分规则

    关闭

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

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