下沙论坛

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

QQ登录

QQ登录

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

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

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

    [LV.Master]伴坛终老

    跳转到指定楼层
    1
    发表于 2019-12-17 09:43:25 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
    设备要求
      已root的Android手机。
      注:下面使用的两个微信安装包,com.tencent.mm.apk为旧版本6.5.16,weixin_new.apk为新版本6.7.3
    背景
      最近在弄一些关于微信的东西,测试过程中,本来打算强行停止后重新启动微信,结果手残点到卸载了。当我重新安装后出现了尴尬的情况,登录的时候,提示微信版本过低,需要安装最新版才能登录。
      

    # u( x0 T6 v* I4 P# p0 B
      但是之前做的一些东西都是基于老版本的微信,所以不能安装新版本,必须想办法在老版本登录才行。
    5 i& y' C9 g, o9 m
    操作过程尝试1、替换版本号
      最开始的想法是,既然要验证版本,那我就把旧版本的伪装一下,让它变成新版本的试试。
      但是,因为没有时间去仔细分析微信是怎么验证的,于是就抱着侥幸心理,写了个xposed模块替换版本号,
      一般情况下是通过以下代码获取版本号的:
    PackageInfo packageInfo = getPackageManager().getPackageInfo("com.tencent.mm",0);int versionCode = packageInfo.versionCode;String versionName = packageInfo.versionName;# x- L+ t) `8 @
      所以去hook getPackageInfo方法,将其返回的PackageInfo中的versionCode和versionName替换成新版本的值就行,
      但是,由下图可知PackageManager是一个抽象接口,
      所以不能直接hook它的getPackageInfo方法,要先获取getPackageManager返回的对象的真实类型,先随便创建一个工程,通过以下代码获取真实的PackageManager类型,
    Log.v("test", getPackageManager().getClass().toString());
    ( h) [" O) ]3 d9 n( C! e+ C$ P2 v8 c7 m1 U  E5 T
    查看日志,可知真实类型为android.app.ApplicationPackageManager,
      然后通过反编译最新版本的微信,获得versionCode和versionName,
      最后的hook代码如下:
    [url=][/url]
    4 ]1 j. o" {; A, J5 P6 _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]
    # {, y8 @/ J- H
    0 f+ D& G  {4 u' h2 Z5 U- i; ~0 G
    4 Q, {0 x: M: P  v3 G, I* Z
      编译安装后重启,一边输入帐号密码,一边祈祷,结果还是提示版本过低,

    / t" e% c7 q, N3 r尝试2、pm uninstall -k 命令
      想着之前旧版本的都能正常使用,说明只要有登录数据,就可以使用旧版本的,所以想着先用新版本的把帐号登录,然后使用 pm uninstall -k 命令,卸载应用但保留数据,然后安装旧版本的。
      先安装一个新版本的微信,
      登录帐号,
    ( E& y1 \5 r4 d5 Z1 A' H
      使用pm uninstall -k com.tencent.mm卸载后安装旧版本的微信,
      结果打开还是不行,还是提示版本过低,

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

    5 P$ ?! }4 }* x' F( i自动化程序
      把之前替换的过程写了个自动替换的程序,代码如下,其中使用的ShellUtils在之前的一篇【Android手机插上usb能充电但不能识别的一种解决方法】能找到:
    [url=][/url]% H$ T# w0 s' ]# k
    package com.example.wxreversion;* w1 w3 s/ P7 V
    ) B" B9 R5 k; h2 u$ Q+ {& z) K
    import android.os.Handler;
    : ~7 I0 b& w7 Ximport android.support.v7.app.AppCompatActivity;
    " ?4 V- A" Y. t6 V' Oimport android.os.Bundle;. a3 c' B& }/ X% w9 A
    import android.text.method.ScrollingMovementMethod;
    ' z( V* Z+ a) ^0 e& Jimport android.util.Log;! U9 a. Q+ D; f5 g
    import android.view.View;- m0 x2 F! e8 r' ~/ }6 v) r% i
    import android.widget.Button;
    , P8 d1 J* |" K$ d7 q6 Z) e' T# Fimport android.widget.TextView;
    0 k: ^# |0 P7 q; s$ }1 k
    ( {+ B: _0 M6 ?* \import java.io.File;
    1 U2 ^0 v6 G' j& e. z) ?) e# _, _2 v+ ^" [$ I
    public class MainActivity extends AppCompatActivity- L# b$ Z, ]$ D
    {4 J# X4 G5 {' Z, i! S; S+ b; ~7 F- x
        Handler handler;+ C0 z" f/ ]8 n
        TextView textView;
    3 U( l( m6 v6 j0 S! q' U$ h6 X, v0 n

    ( Z) Z; u8 L2 R3 [% ?; D+ X    private void LogV(String s)" T6 a2 A8 _* i, Y
        {
    1 G/ d! u* ^% M+ ?/ j        Log.v("test", s);
    . S& C9 j" t2 t  s    }
    0 B3 \: B3 H! c! O$ Y& Y6 j$ d+ g* q  F, Z2 F2 R
        private void textAppend(final String s)
      h. Y* }6 Y2 h7 b9 {' D    {
    5 t! l# v. h# a$ `, n# F        LogV("textAppend:" + s);
    6 _5 p0 ]9 ^6 m" o) g, Y        handler.post(new Runnable()
    # S6 D" E$ I- k" J8 Z        {" b# H- Q  T% g# K0 T
                @Override# k; n# _% _/ T) x2 _
                public void run()
    * n* A! O# l" J% }1 O            {
    ! U/ P8 [6 _8 Q( s: \4 v, e) @                LogV("run:" + s);
    0 W& ?9 \5 p1 e* Q- z. L1 J* ?8 O
                    textView.setText(textView.getText() + s);
    7 S6 D" l9 Z  z7 m$ i* Q: x" \) o; p            }
    + f  V6 ]3 C( {9 M/ m: {        });
    ) N- W; P* S. }4 I6 Q7 @, j$ W    }0 ]% C% S8 G6 `/ `& x

    ; i, A, r& D# ^9 w: y3 s) q/ g    private String getPath()3 E5 @6 z) Q8 b6 n. n
        {1 O) L( A* L' @. W! @
            String path = null;4 G9 c+ m& C+ B- p1 D
            textAppend("-----------------------------\n");" _  R6 T9 M( u" J7 l
    , z/ p5 o. j8 U# }7 A7 e
    2 ?5 |$ @2 y% p" d) m
            if (!ShellUtils.checkRootPermission())( @1 H3 f( J( B' P! Q
            {
    7 x/ T1 J9 H3 e6 y  p% W( z! L            textAppend("获取root权限失败,请在设置中授予权限!\n");
    2 g7 K5 D( O3 s/ X            return path;
    ! q; i5 L2 X6 W/ q- f: V0 @, y        }6 u+ _. i1 V0 d6 X  X6 `

    5 X: ?  k: T: {' p- s2 K        path = ShellUtils.execCommand("pm path com.tencent.mm", true).successMsg;
    , u! ~& K9 c* Y3 p7 R% x, X! r# z+ U        if (path != null)
    ' g+ v" y. ~4 D- s        {
    0 m* ]- h  @$ `            try
    9 {8 w; @1 X9 ]! J  s& ]( c, v5 B$ E            {& G, q. ~) x$ ^. b; Q' z4 P$ q" h
                    path = path.substring(path.indexOf('/'), path.lastIndexOf('/'));* [/ t4 x+ ~; _4 u+ J
                } catch (Throwable throwable)
    , q( O5 J. y6 k& r0 C3 @* L+ R- v! c            {: w9 Q& Q. m3 k1 N2 @; S
                    path = null;
      Q. ]% f  U4 S7 F, R2 r3 u            }
    1 R* G. Z' e+ ^        }
    7 D1 g; I& a: O% h' \# l  I
    . n( B- Y  F4 k7 h        if (path == null)
    % K: t6 N" i' }3 G        {
    6 B# {4 @% U/ Y. B0 l( j& A            textAppend("未找到微信安装目录,请先安装!\n");. \5 l' K& v/ p" H" t. F9 x* x4 I
            } else
    . c4 B# |: n: }  }0 `+ o6 l        {' h7 S+ F& I1 c
                textAppend("找到安装目录:" + path + "\n");& d+ Y' Y& J3 d0 f$ E
            }
    0 S7 m$ Y- S: \$ d2 v9 E
    - O5 `2 {7 o4 g8 s) e4 G        return path;% R8 b8 _. w+ A
        }, \* W* L1 L/ D8 B+ b

    , r& b  N! y3 N  y1 b7 R8 ]0 a    private boolean isEnpty(String string)
    3 e  \& [- Q) Z6 U+ S" l    {
    ; d2 X0 N+ k( f0 ?        if (string == null || string.length() == 0)
    7 K! v/ l  m8 l        {
    ) P# k; e' h1 y: x            return true;
    + S9 C" ^: A- w7 u9 z        }5 C6 e" z" X4 B
            return false;
    5 ^; R3 {& C+ m  h+ a7 ^    }4 b) l- G& H8 c! G& o% @( p* O
    % d' w! i, K. K7 U/ H- Y
        private void putResult(ShellUtils.CommandResult result)2 ?3 X/ G0 f/ o7 |5 Z
        {2 K$ g. u& H: A& [, S" g7 `
            textAppend("返回码:" + result.result + "\n");
    : g. ]) P. k" N( H; p3 S# e3 n" n$ J
            if (!isEnpty(result.successMsg))4 w2 H% j6 ?6 m2 }! h
            {7 j$ y" L" P/ R) |" ]4 T% h
                textAppend(result.successMsg + "\n");
    # g( _; @3 b  d1 \7 A        } else if (!isEnpty(result.errorMsg))0 p, }' ]0 d; w* k, Q- D
            {
    8 B/ @5 T, u% a) a2 i            textAppend("错误消息:" + result.errorMsg + "\n");
    7 j$ F7 \! N5 n3 R( T- N        }# q: C1 U! O" o
        }1 p! n9 J2 `! \5 y/ }6 R2 V- b8 @. \
    7 q' k% P7 [9 [& E8 O6 g
        @Override7 `, D, q. n( r" n2 x# o8 {; M
        protected void onCreate(Bundle savedInstanceState)
    $ h6 S2 h5 h, M, j    {( n; H1 y5 y! V/ E! }
            super.onCreate(savedInstanceState);0 v4 I4 ^, v! C3 ]8 o& U
            setContentView(R.layout.activity_main);
    " I0 _4 t4 q6 V        handler = new Handler();
    ; e, n/ I& Y% ]* @9 u, O
    ) e, H1 P' l4 x3 N! W        textView = (TextView) findViewById(R.id.textView);- ?/ y1 O* `* o( `. v. q
            textView.setMovementMethod(ScrollingMovementMethod.getInstance());) ~, {5 Z- a/ C, v; z0 E; e% [8 Z4 C# t* b

    ; Z5 Z! L" G9 n        ((Button) findViewById(R.id.button1)).setOnClickListener(new View.OnClickListener(), n& P: _6 `/ }2 H! x' j8 y
            {
    $ V* n+ R) e3 B5 |            @Override
    3 ^& L( [8 E1 n- n            public void onClick(View v)
    ( h1 ~0 A( K* G+ o9 H% v            {7 t3 |" [  u2 C6 S; K
    1 L# V7 E3 ]: I1 V
                    new Thread(): l' j! y+ e1 v/ Z3 \
                    {
    ( E8 d- T/ u( ]) V                    @Override
    3 x! h6 R: ]$ Y* i8 c9 M8 L, Y                    public void run()4 ?. Z' A; A5 \" w
                        {
    ! r5 |$ m7 q$ n& i; }5 {  k                        String path = getPath();
    8 D0 C" M  r& Q  v* w3 `                        if (path == null)) e; P0 f! B( G5 \. s! ~7 s
                            {. K( z- C+ N5 F( c
                                return;( e( D) k( h/ |$ f& Z
                            }7 H+ O- A8 u# O( O& s6 ?
                            textAppend("正在保存安装目录!\n");
    * u# C5 v/ ~1 P4 C/ ^                        ShellUtils.CommandResult result = ShellUtils.execCommand("cp -af " + path + " /data/local/tmp/com.tencent.mm", true);6 Z. ?7 O' G" ^
                            putResult(result);+ P' r/ [( N5 B, S# }- q
                            if (!isEnpty(result.errorMsg))
    - \+ z: l5 \; ?% a5 |3 H$ ^                        {  f0 K2 J& K: ]; `1 Y3 L* E4 {
                                return;
    * K9 ?2 Z1 w5 g                        }
    $ G. ?% C! V8 F5 l3 J
    9 I: c5 G6 P% i# I4 D' Y1 @' W7 A                        textAppend("正在卸载微信!\n");/ A# o0 d1 d9 {# a) {( W
                            result = ShellUtils.execCommand("pm uninstall com.tencent.mm", true);//-k无用
    ) r8 ^) L6 v5 K8 V* ?6 @                        putResult(result);
    : S1 [8 b0 F, X- Q2 e) F                        if (!isEnpty(result.errorMsg)), p. _& Y# `6 L3 T: {
                            {
    + C/ W( c4 }3 E                            return;
    2 |6 Z" m3 M- r                        }
    ! e7 D- [7 [) u
    6 k. _' ?. m5 _5 I% G: f                        textAppend("请安装新版微信,并在登录成功后点击【覆盖安装文件并重启】按钮!\n");1 `& J9 }: Y. N  \' m+ y5 M
                        }
    # O6 q0 N6 |# z" o                }.start();
    3 k: {% O) a! d: M( b" W& k6 Y5 q" }8 B5 ~
                }) h4 @& P  g4 _. f! ?
            });
    / `8 Q1 ?, j3 N9 w* ?$ i, \$ w' ~: N- A, b  H
    " x$ e& Q& h) E3 H) |4 K( {
            ((Button) findViewById(R.id.button2)).setOnClickListener(new View.OnClickListener()/ r# J8 @% Q% L# e1 `
            {
    ) N0 g: S, ^! O$ I8 |. ^. M            @Override
    0 p0 X( b" h$ w6 @$ M            public void onClick(View v)+ B. W$ U2 E1 K# L% J! J
                {: W) h3 }+ P% Y0 C8 o0 I" R6 F( ~, y

    ; a$ e# P: ]9 {' b+ ^; T! Y                new Thread()
    - I% P5 |! G5 B& M# U1 \* |% z                {, ?) `# s2 x$ _& P
                        @Override
    : {6 J, Z. c" I* ]/ f                    public void run()) |  z5 ?% J, U& j
                        {  S. ~7 R. Z. H. |/ z/ g
                            String path = getPath();
    - h3 r, G- U9 o  X( I' S; s) ]                        if (path == null)0 [" D0 V" l% i' b% D6 E
                            {, M* f3 {- k" z( [8 _: z
                                return;
    9 U8 L, f4 B* N  h. g                        }
    ; @4 N  \/ j  R
      r+ l4 P! G2 V2 z. Q5 N                        textAppend("正在检查是否有备份的安装文件!\n");3 x) J- }! L; _. S
                            if (!new File("/data/local/tmp/com.tencent.mm").exists())7 h1 p. G* T) \/ Q
                            {1 v1 Y6 J& L% }9 ]/ C
                                textAppend("不存在备份的安装文件,请先安装低版本微信后点击【覆盖安装文件并重启】按钮!\n");1 V- I* C- D! o$ q  E8 i$ Q0 e% j% o
                                return;; W' T2 j5 I& o( X* Y
                            }$ A& Q: g  h  C! R7 v

    , m4 u4 m& m7 u- M8 v' k  f3 P                        textAppend("已有备份的安装文件,正在删除当前的安装目录!\n");
    & G: c& Z/ W  B4 f- j' t/ P  K                        ShellUtils.CommandResult result = ShellUtils.execCommand("rm -rf " + path + "/*", true);( G9 o6 n* a; l* R7 R0 A( ]
                            putResult(result);
    - n3 V6 e. W6 d% V" \3 u2 j* p                        if (!isEnpty(result.errorMsg))
    5 {2 A* y! X* D                        {6 K7 K3 g& q- s6 w3 l$ H. Y* C
                                return;
    & Z( [7 N( i# G6 r! ^9 [                        }
    % t# ?4 q/ E2 h# n  e, ~( B+ j* G, g' C8 ~5 J6 y; B

    + ?; G) j# s! l* S5 W: [                        textAppend("正在覆盖安装目录!\n");
    ) @8 C7 k$ h9 z9 ?: I                        result = ShellUtils.execCommand("cp -af /data/local/tmp/com.tencent.mm/* " + path, true);
    2 E; \7 `3 f+ d1 |/ }% S" d                        ShellUtils.execCommand("rm -rf /data/local/tmp/com.tencent.mm", true);, ^9 c( A  d5 I$ K% c; Y
                            putResult(result);; w" o  c/ N1 p" B; k
                            if (!isEnpty(result.errorMsg))  H- l& ?* k# g) m) e9 i( T& S  r
                            {
    * P# _% P/ H% z! o                            return;. U0 h; D  c! p3 {& R
                            }
    ; q6 M5 {7 F( @6 F* |( l
    : a1 v  `& H3 ]; h! N# i                        textAppend("系统将在10秒后重启!\n");7 o5 A. C( t1 V1 k
    8 n( x9 X; G6 |% c2 O
    & j; e+ a' m$ @0 s! e
                            try
    / J/ r$ N' t! I) \+ D                        {' H; x3 Z9 r+ {
                                sleep(10 * 1000);
    - N) e! J7 e/ b- P, ]                            handler.post(new Runnable()9 }' {& |: c6 R. Z% Q
                                {
    4 L/ @; Z0 J* R# O* `9 N! e                                @Override8 ?/ E8 k# z! ]* h+ p
                                    public void run(): W5 `6 ^! @/ \9 s1 j
                                    {0 U2 N( m; l) ]  p3 ?. b2 \! a. D% [
                                        ShellUtils.execCommand("reboot", true);0 W5 w' t5 X3 J# l( R0 F7 b
                                    }' a6 J( d8 C7 F8 f
                                });
      i$ {5 c: A0 f- y/ K                        } catch (InterruptedException e)
    3 f/ x5 J5 s0 E                        {
    3 V1 K, [5 ]1 G                            e.printStackTrace();
    2 w; @0 A: R& I                        }
    1 ], N# h) f: `" w% h# C0 L/ u                    }+ |- ]# p4 u- t
                    }.start();: p/ ~" O; Q4 T3 ]; a5 U7 G/ c

      a8 v- |% J4 v1 s% @  E% k            }
    0 Z. F; A7 B; v( ?        });- ~5 w  Z0 K$ x# J8 H

    ( v! y5 P( T# ?7 J        textView.append("-----------------------------\n");
    ) h5 w; J4 Z6 C: e* Y9 m        textView.append("该应用需要root权限!\n");
    8 ?9 d& W- M3 _: T, P0 ]        if (ShellUtils.checkRootPermission())
    $ A5 P4 P5 ?0 Y6 O6 w6 _( w        {
    ! V# B' P) f+ [6 C            textView.append("获取root权限成功!\n");" m$ X& P4 [# K) H& Y+ j
            } else1 O' {% p% g" J2 W  K
            {
    7 u9 r. ?( E; _2 ?# y& q, Z; z( s            textView.append("获取root权限失败,请在设置中授予权限!\n");
    , r* O; N: d" _* s        }
    9 e2 m! L3 B! E9 j
    5 t5 _9 W* k, A( q9 h
    ) a. I, t/ A7 K! }6 K8 p    }) R# g+ t  a, F& @: X( D: ~
    }[url=][/url]
    2 b. p. K, `# _" Y6 U
    - |4 f* z0 ]# Z$ f+ e

    - o+ `) o) \' V* s3 c* `( ^
    运行如下:
    先安装旧版本微信,
    运行该程序,点击左边的【保存安装文件并卸载】按钮,
      安装新版本微信并登录,
      点击右边的【覆盖安装文件并重启】按钮,
      重启后重新输密码登录即可。

    ; N2 Y- x7 ?  `
    完整代码 wxreversion.rar
    安装包在release目录中

    ; o7 A. S% P# X6 f9 u& `
    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏 分享分享 顶 踩

    本版积分规则

    关闭

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

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