下沙论坛

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

QQ登录

QQ登录

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

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

[复制链接]
  • TA的每日心情
    奋斗
    前天 09:20
  • 签到天数: 2383 天

    [LV.Master]伴坛终老

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

    & x: ~3 E! [+ v% f8 T7 S  Y操作过程尝试1、替换版本号
      最开始的想法是,既然要验证版本,那我就把旧版本的伪装一下,让它变成新版本的试试。
      但是,因为没有时间去仔细分析微信是怎么验证的,于是就抱着侥幸心理,写了个xposed模块替换版本号,
      一般情况下是通过以下代码获取版本号的:
    PackageInfo packageInfo = getPackageManager().getPackageInfo("com.tencent.mm",0);int versionCode = packageInfo.versionCode;String versionName = packageInfo.versionName;+ t5 O6 ^( x, I8 }  f4 }
      所以去hook getPackageInfo方法,将其返回的PackageInfo中的versionCode和versionName替换成新版本的值就行,
      但是,由下图可知PackageManager是一个抽象接口,
      所以不能直接hook它的getPackageInfo方法,要先获取getPackageManager返回的对象的真实类型,先随便创建一个工程,通过以下代码获取真实的PackageManager类型,
    Log.v("test", getPackageManager().getClass().toString());2 u: V$ I( I; g" Y, k, g' Y) F! }
    . i2 [1 L* K- ~- w& Z' W% T
    查看日志,可知真实类型为android.app.ApplicationPackageManager,
      然后通过反编译最新版本的微信,获得versionCode和versionName,
      最后的hook代码如下:
    [url=][/url]
    # T$ h4 s2 R7 O$ S, M9 _5 wif (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]
    : ^1 b; [0 B, \4 _& p

    # U( p: w  v6 r. e- V' h" y% k6 Q1 _! V) B8 N
      编译安装后重启,一边输入帐号密码,一边祈祷,结果还是提示版本过低,

    0 n$ a6 v+ z4 n尝试2、pm uninstall -k 命令
      想着之前旧版本的都能正常使用,说明只要有登录数据,就可以使用旧版本的,所以想着先用新版本的把帐号登录,然后使用 pm uninstall -k 命令,卸载应用但保留数据,然后安装旧版本的。
      先安装一个新版本的微信,
      登录帐号,
    8 p1 Q0 n+ ^7 g
      使用pm uninstall -k com.tencent.mm卸载后安装旧版本的微信,
      结果打开还是不行,还是提示版本过低,
    - d1 ]6 V+ M# \: I- t% E
      于是怀疑卸载的时候数据被一起删了,根本就没有保留,再次执行pm uninstall -k com.tencent.mm,查看data目录,微信的目录已经不存在了。
    尝试3、adb install -r 命令
      同样先用新版本的把帐号登录,然后使用 adb install -r 命令强制安装,结果还是不行,不能安装比当前版本低的,,,
    . d  j0 }! X9 [) y) |6 P0 @
    尝试4、替换安装目录
      既然用 pm uninstall -k 卸载时保留数据不行,那么就尝试手动替换。
      首先安装低版本的微信,把安装目录复制一份,然后卸载。
      再安装新版本的微信,并登录帐号。
      用之前保存的旧版本安装目录替换新版本的安装目录,然后重启手机。
      重启后提示登录错误,重新输入密码即可,
      不知道为什么,这个手机在我写这篇博文的时候,关于微信的页面还是新版本的版本号,而我之前弄的另一个手机就是真实的旧版本号,
      但是这个手机系统设置中微信的版本号已经变成旧版本的了,也不影响使用。
      另一个手机的,
    / U, V% H2 |# }" h4 ^, k# S1 ]
    自动化程序
      把之前替换的过程写了个自动替换的程序,代码如下,其中使用的ShellUtils在之前的一篇【Android手机插上usb能充电但不能识别的一种解决方法】能找到:
    [url=][/url]
    7 z! `* A. D- P$ T# k" i8 G, c% _$ gpackage com.example.wxreversion;6 u+ j1 I% j! H9 _; Y9 w/ T; F& P7 n
    , {8 A0 _# E+ J* u( o) y
    import android.os.Handler;9 k( M: ^9 ?4 f2 W/ @+ I  z
    import android.support.v7.app.AppCompatActivity;  S3 k: r2 I; v6 {" j
    import android.os.Bundle;/ ~) F. T9 M! k+ ^' Y
    import android.text.method.ScrollingMovementMethod;
    ( m' @" D4 B/ n; c* g( Cimport android.util.Log;2 O, d( o. m$ e: t) Y
    import android.view.View;
    2 r5 ~+ O& L9 B. f# F" Q, ]import android.widget.Button;
    ; m( I* k0 u  L; p( j2 C$ @# H6 fimport android.widget.TextView;* _3 K5 P; T4 f+ B2 j, b2 {& M+ s, ?/ ~
    " y+ @6 n3 Z4 D8 z$ X) F7 s) M
    import java.io.File;% K( K. O1 G* y  j3 C/ X& f: D1 o4 D

    3 I" v5 a( s4 y0 |: d; _! P! }public class MainActivity extends AppCompatActivity' i6 s$ [  h" D# L
    {
    ) m- F3 L  i) u    Handler handler;5 S9 S% O8 m, Q" n1 D; o$ _9 o
        TextView textView;
    - R  T$ a  _5 J' p0 N8 y
    . m( x7 N# G' _0 C& d
    ! K" a" \  c' A- J    private void LogV(String s)- b" H. U5 u( M' L# n
        {3 _6 X* o7 `4 L3 f, N. m
            Log.v("test", s);2 D" j  K" f7 Q; e# |+ g: e
        }
    4 G  L: c! c" b+ I3 R) Q3 r3 K$ ^+ s8 M# C5 L  I+ b4 {
        private void textAppend(final String s)
    , S( n: e: h6 p$ h( P" ^/ U: l6 R    {2 F4 u. P" s+ u# D* j
            LogV("textAppend:" + s);
    ! a/ S) l9 F& n! }        handler.post(new Runnable(): E) _* M) o% ~- i$ J- Y) J$ Y
            {0 }) U3 X6 c" q: P" z% n
                @Override
    - d$ C- P* h0 h% L" g' k            public void run()% m2 x$ n2 v# h# G# t7 L
                {
    $ W6 w; L5 K7 }" @* ?3 _& \                LogV("run:" + s);
    # N, r; A9 a3 r$ T* v1 ~
    6 l1 r8 N$ o4 h8 T                textView.setText(textView.getText() + s);
    * D3 e" Z- h# S. V5 C            }+ I2 F& b  g: F; I3 \& y) c
            });+ s* D( K1 G+ z  }) @, f
        }
    * x* K" ^- T  H$ d$ g( {5 f0 f6 e$ {* W) V8 V" m( W
        private String getPath()
    . h! \7 U4 n) s+ T6 K2 C7 d    {  q3 t2 J0 P3 e6 g$ E
            String path = null;
    . A, C% K" P6 E0 C& g) a0 k        textAppend("-----------------------------\n");8 ?$ v3 A- y+ A- O. d6 x0 j+ A: W- j

    % A# a  @4 O5 u. B$ |
    6 h! l( b. u% {; z        if (!ShellUtils.checkRootPermission())' n, X4 N1 D, J0 u( J
            {
    ) ~  v+ M! P$ q            textAppend("获取root权限失败,请在设置中授予权限!\n");
    ; e: C% p7 D) D: }! x  {9 D7 [            return path;2 L* e, P8 v* q3 a7 T
            }! h  n/ l4 E0 j$ b

    " ]- X5 U$ }) `3 \& R6 P        path = ShellUtils.execCommand("pm path com.tencent.mm", true).successMsg;" y# b0 C) B& b
            if (path != null)$ w% J' i+ L# @/ D3 y; s' ]1 t
            {$ \3 k& F. Q- D0 q$ t/ M$ m
                try4 N- ^0 \$ w- G* \
                {( h3 s. a2 V' Q( N
                    path = path.substring(path.indexOf('/'), path.lastIndexOf('/'));
    3 Q7 S8 [" w/ ~: l8 N: y            } catch (Throwable throwable)$ |3 @2 |, i4 u9 G, t
                {2 a! N8 L0 ^4 |& C5 D
                    path = null;
    1 y) D6 u' S) K) G, V            }
    ) L, ]. ~7 H, h4 H& c) T" l% U8 V. q" }        }- c% e3 f$ T2 M- j5 [* `9 U
    5 I6 e, s7 ^" z8 M+ U
            if (path == null)
    9 b, v- \6 }- k  e7 n        {
    / o5 K7 p& E/ G8 n9 {            textAppend("未找到微信安装目录,请先安装!\n");2 ?5 O0 i- F; h! u4 I2 n, a8 g$ ?
            } else, K) z2 o% s; p- @7 N4 G0 A7 M
            {6 O/ {7 K. W# s& J! w
                textAppend("找到安装目录:" + path + "\n");9 T* `6 ~/ w( c5 m% k6 `$ K
            }. s+ N; Z5 k; |% K, ^" n8 ?

    # x- ~; j/ T& D- W7 S. w$ G0 @: d        return path;2 \* Z* z% V: ~" E7 U& {
        }
    ) `4 J' V6 t' J8 f: w. w4 a8 n
    ) _7 r) a4 e. K    private boolean isEnpty(String string)
    ) V3 `! O7 h* q6 R% m    {! r4 f2 G. t7 \3 m" v& q
            if (string == null || string.length() == 0)( o0 P- D5 q) D, w# d7 U
            {
    ( I0 ^- H$ H; g0 q& T% ^+ w            return true;
    : |4 |% W- U% b) J7 A9 _6 c) {        }+ w0 V" R8 z% b! ?  W
            return false;4 I/ J. _5 O0 }6 k: x4 W+ f. b$ Z* ^
        }
    5 x% e7 a' r6 T5 y) b
    ' q9 ?9 {8 w' D" O+ f  e$ Z    private void putResult(ShellUtils.CommandResult result)
    # f2 a  j, R5 V) r3 F1 y    {
    ' Y$ \* ^% v8 q+ a/ A        textAppend("返回码:" + result.result + "\n");5 B6 R8 P& ]5 A- q& @3 Y' n
    7 l" D4 x7 O/ Z, D
            if (!isEnpty(result.successMsg))3 l0 Y% M9 W6 a, o& N+ i
            {. A5 B' }, D# d. W% m. h/ G7 C
                textAppend(result.successMsg + "\n");
    - F7 Z; {2 X) l. X4 _% ^6 C6 l        } else if (!isEnpty(result.errorMsg))( ^+ B( M. U0 s
            {
    # ~5 n2 x8 ]. A& Z3 }& N/ x$ q  l            textAppend("错误消息:" + result.errorMsg + "\n");$ C# h& w0 {1 K9 H
            }
    8 \8 Q* f8 g  _% P+ f    }
    ( Q7 z/ k' v0 a6 J( }6 [# J
    ' U0 N- U- F. ]2 V" \* S! g    @Override
    0 N2 @/ G* w4 J* j2 {    protected void onCreate(Bundle savedInstanceState)5 S& [2 t9 i5 x/ R0 g% T, S- _
        {9 J  Y+ D2 l+ c2 S. `2 B7 B; f  v
            super.onCreate(savedInstanceState);
    , J, I+ U( z- H' ?: j3 W        setContentView(R.layout.activity_main);
    " E- W6 e0 h' V        handler = new Handler();  s, C  A# z8 |8 R1 m# ?$ e) J+ X5 i
    ) U& g2 H  Q: |, r( c$ i0 K
            textView = (TextView) findViewById(R.id.textView);! e0 P1 G! U& I6 Z1 k
            textView.setMovementMethod(ScrollingMovementMethod.getInstance());' ^8 x* J* ^4 {; e' g% Z
    . G3 G( i. u, O: a# e
            ((Button) findViewById(R.id.button1)).setOnClickListener(new View.OnClickListener()
    0 a0 H2 d% U8 R6 `        {
    / n* ]) ~. }: c. g            @Override
    . I3 v( x! [! _            public void onClick(View v)( i) _$ r+ v& Y' \( d% ?3 Q4 u
                {
    2 z; {# M) |+ D7 n( }: Y2 g
    3 k+ |4 J1 X4 V8 |: V% S+ n6 R9 }                new Thread()/ o2 e9 }& A7 y- P' z1 M
                    {  Y# r' U& n4 `/ C
                        @Override; A% S9 z! ?! e+ ~$ J1 p6 z( _
                        public void run(), Z5 i1 ~9 `! @! Q$ a! ~
                        {
      g) N- A0 w4 t. f7 j0 w# O                        String path = getPath();  O( n% A- O, t8 N) F  t: t, N
                            if (path == null), o# x2 R  a5 S6 L: p8 T
                            {9 T# v5 C1 S6 z
                                return;
    2 _; g, t$ P6 g8 I( l+ n                        }0 F' q- C, A; S" S
                            textAppend("正在保存安装目录!\n");
    , L7 j& e4 I4 @- B  n8 p2 J: A: \                        ShellUtils.CommandResult result = ShellUtils.execCommand("cp -af " + path + " /data/local/tmp/com.tencent.mm", true);
    7 i- Z% E* z9 l+ Z# q                        putResult(result);/ m" Q0 H6 P: b  p! P
                            if (!isEnpty(result.errorMsg))
    8 |  B& t- P9 h9 S+ o0 \- a                        {* I, U3 I. E2 \0 S, v0 b* U' D) J, r/ d
                                return;
    % ~3 E( T$ A4 s9 i7 b- m$ f9 m& {                        }  A, V) ?6 v2 |- ]5 M: c

    # w- K% t* ?% ]) ?) A! {                        textAppend("正在卸载微信!\n");
    & ?/ R& Z3 N9 V7 f                        result = ShellUtils.execCommand("pm uninstall com.tencent.mm", true);//-k无用
    8 |0 x  l1 `. S- X1 F* c                        putResult(result);
    % s$ {1 j" n2 `8 D. Y                        if (!isEnpty(result.errorMsg))
    ; Z; J% X- T" _$ T, w. ?# ]* N: ^                        {
    - T$ F: Q* `8 o* B& \                            return;- `0 H) y2 B  C
                            }
    ) H7 E$ ?' v0 ~$ `. f
    9 h& l8 w7 F! }                        textAppend("请安装新版微信,并在登录成功后点击【覆盖安装文件并重启】按钮!\n");% d7 h* U- z0 w* g7 w+ p
                        }. [( ]- ]' z; K! h8 a' e8 A+ q3 V
                    }.start();7 f$ {  I8 I4 T6 P, _

    + y+ g8 \4 T1 p            }
    * b/ e' {. G+ R8 [        });6 b, ^$ {8 J( v1 `

    4 `* p' h, p: J$ h4 c; y6 u9 t1 {! w) Q9 d3 e. q
            ((Button) findViewById(R.id.button2)).setOnClickListener(new View.OnClickListener()/ M! \: O+ \# \9 t8 P
            {
    % P6 ~- \" V4 x            @Override
    ' T: C& F: z, E6 N            public void onClick(View v)
    ! S8 `% Q5 ]. j; K- H! v            {
    $ S5 G9 n) M% L5 x) i& g5 w: U8 y
    8 V: i, \& q" F$ q4 J  m, h                new Thread()
    8 A" V8 n6 d9 V- U% a* |                {
    & G2 U0 @+ f4 l1 T6 i4 B. s                    @Override
    9 M. a% L" x  r                    public void run()
    4 I- E; D0 S: \5 W                    {$ f  B+ @% N- \4 N; V: @$ Z5 ?$ M
                            String path = getPath();$ b$ a6 X* h# s, B
                            if (path == null), T% l0 o( Q' a2 f% ]/ }
                            {: @7 ?4 j: O, J( p: w' J" f
                                return;
    # f/ I8 v, b/ B( n2 P& G( W9 G                        }- f9 {  C. g7 K

    9 s4 d7 N6 N' Q1 h# c! [: r+ |                        textAppend("正在检查是否有备份的安装文件!\n");
    + g- n2 L* N2 c3 {                        if (!new File("/data/local/tmp/com.tencent.mm").exists())
    3 y$ y! Z0 r/ `  w: |9 s( d. l                        {9 w4 |# w4 _, N; U, U
                                textAppend("不存在备份的安装文件,请先安装低版本微信后点击【覆盖安装文件并重启】按钮!\n");
    ( w+ P. K7 s9 \2 v. q                            return;" S( I0 N! e- L/ r& W0 j( v
                            }% R2 D  n! b0 v

    & I0 K5 h- I0 D$ Q9 Z                        textAppend("已有备份的安装文件,正在删除当前的安装目录!\n");
      W/ J! @; |! s5 z$ F2 B                        ShellUtils.CommandResult result = ShellUtils.execCommand("rm -rf " + path + "/*", true);, J0 e$ u8 W! ^3 B6 v7 O
                            putResult(result);
    . c0 \3 c( k7 D* u! m$ k) H" C                        if (!isEnpty(result.errorMsg))2 P& X. W3 t( Q2 Q0 `/ Z  {7 C
                            {3 e3 r# Y& s; b" {6 W
                                return;
    7 ?' U+ f+ B; G+ \& K8 o5 ?/ U                        }- S( q2 u# C+ X* e' w4 t6 w

    2 A* \( k/ b: _) o( X9 H0 d$ y9 s4 H$ W- \- l
                            textAppend("正在覆盖安装目录!\n");2 a( w$ M" E9 f$ z3 G, @
                            result = ShellUtils.execCommand("cp -af /data/local/tmp/com.tencent.mm/* " + path, true);7 E, C1 y9 K% s
                            ShellUtils.execCommand("rm -rf /data/local/tmp/com.tencent.mm", true);- J* I# s) t, Y3 ]% \+ c) S6 y/ ?1 h
                            putResult(result);$ X6 g- q3 O) K* Q& p5 p
                            if (!isEnpty(result.errorMsg))
    0 C2 |4 f+ _, v. O# x. U/ \                        {+ E) f: o8 \) T# u
                                return;+ T1 {6 H4 ~4 [' o2 ?2 t2 G# Q
                            }5 Q9 M4 v0 d: Y+ g, r, Z

    6 p" T0 D* C4 e0 r4 ~) w/ w+ k* t% b                        textAppend("系统将在10秒后重启!\n");; A: J. K* t/ K& E0 _& T

    + O: b; a+ r3 m9 J
    9 G- L5 O- c0 A% ?  y                        try- W. R( Z- c/ I- ^) g
                            {
    5 @  r5 S. H* ]! R                            sleep(10 * 1000);  W  ~3 m1 Z7 |- d+ P- q
                                handler.post(new Runnable()+ `5 U) S8 o! a; R2 `/ B
                                {: Q& g6 l  R+ Z5 k; n# U7 m$ d( _; c" O
                                    @Override
    % M/ I, F6 @. s/ b$ w2 J6 ?                                public void run()+ d$ G/ f0 e; A) q; G' r$ }% t8 S
                                    {) J# x+ x% V  B; d* y
                                        ShellUtils.execCommand("reboot", true);
    8 w/ P+ `  C, N, r) ^8 g, x                                }
    4 l# Q( u0 s$ t( O: y                            });
    0 w& u  ^' o) R1 Y' y                        } catch (InterruptedException e)
    - }" I) G7 F! ]                        {
    ' f! C' z; X/ Y2 f& S. }                            e.printStackTrace();
    ; }* h# @; ~( |; @% [( k+ _                        }4 C+ f- s2 c6 E2 S4 b5 e/ e
                        }% R3 I  X% `7 d. ^6 L0 r1 _
                    }.start();) |9 X% ?+ a: G' ]

    # j* _- ?- r' B, `            }" P# Z. |; c7 K3 t1 z/ H; R5 {4 s
            });
      H6 A( f0 D5 w  @, ~8 A4 o% Q, p7 g! s( S
            textView.append("-----------------------------\n");+ q/ r3 D9 W; r. o) }+ B
            textView.append("该应用需要root权限!\n");' X& T* {( W& e) X# S
            if (ShellUtils.checkRootPermission())
    + H/ @  @; I/ F6 Y$ q3 h' X        {9 q# i; {9 Y( \2 {; N' t, b
                textView.append("获取root权限成功!\n");- V0 [4 C: Y) F
            } else, P, k- L' H6 u% z  L0 B2 `) s7 K
            {
    2 v5 T" B$ ?' j9 o            textView.append("获取root权限失败,请在设置中授予权限!\n");
    0 q/ W1 h2 H# u+ w5 R5 O        }  i+ O& A/ @, [# S: a
    , O6 Z$ V% S3 \$ ^4 [% [+ h
    * r4 j/ S7 @& U3 G9 w
        }
    $ V- M: p) `# m! u( s0 V# t}[url=][/url]6 L2 K2 S, O0 d4 W6 P& y* ~
    # H: t; J3 O! C1 D- r$ g. y; Y4 b
    5 x' o$ l  b1 A8 `5 A! y
    运行如下:
    先安装旧版本微信,
    运行该程序,点击左边的【保存安装文件并卸载】按钮,
      安装新版本微信并登录,
      点击右边的【覆盖安装文件并重启】按钮,
      重启后重新输密码登录即可。

    5 Z+ h% ?* f9 p+ s9 u# @' {$ Y
    完整代码 wxreversion.rar
    安装包在release目录中

    6 _+ t7 r! |0 ]( _
    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏 分享分享 顶 踩

    本版积分规则

    关闭

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

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