微信降版本登錄


 設備要求

  已root的Android手機。

  注:下面使用的兩個微信安裝包,com.tencent.mm.apk為舊版本6.5.16,weixin_new.apk為新版本6.7.3

背景

  最近在弄一些關於微信的東西,測試過程中,本來打算強行停止后重新啟動微信,結果手殘點到卸載了。當我重新安裝后出現了尷尬的情況,登錄的時候,提示微信版本過低,需要安裝最新版才能登錄。

  

 

  但是之前做的一些東西都是基於老版本的微信,所以不能安裝新版本,必須想辦法在老版本登錄才行。

 

操作過程

嘗試1、替換版本號

  最開始的想法是,既然要驗證版本,那我就把舊版本的偽裝一下,讓它變成新版本的試試。

  但是,因為沒有時間去仔細分析微信是怎么驗證的,於是就抱着僥幸心理,寫了個xposed模塊替換版本號,

  一般情況下是通過以下代碼獲取版本號的:

PackageInfo packageInfo = getPackageManager().getPackageInfo("com.tencent.mm",0);
int versionCode = packageInfo.versionCode;
String versionName = packageInfo.versionName;

  所以去hook getPackageInfo方法,將其返回的PackageInfo中的versionCode和versionName替換成新版本的值就行,

  但是,由下圖可知PackageManager是一個抽象接口,

  所以不能直接hook它的getPackageInfo方法,要先獲取getPackageManager返回的對象的真實類型,先隨便創建一個工程,通過以下代碼獲取真實的PackageManager類型,

Log.v("test", getPackageManager().getClass().toString());

 

查看日志,可知真實類型為android.app.ApplicationPackageManager,

  然后通過反編譯最新版本的微信,獲得versionCode和versionName,

  最后的hook代碼如下:

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;
                    }

                }
            });
}

 

   編譯安裝后重啟,一邊輸入帳號密碼,一邊祈禱,結果還是提示版本過低,

 

嘗試2、pm uninstall -k 命令

  想着之前舊版本的都能正常使用,說明只要有登錄數據,就可以使用舊版本的,所以想着先用新版本的把帳號登錄,然后使用 pm uninstall -k 命令,卸載應用但保留數據,然后安裝舊版本的。

  先安裝一個新版本的微信,

  登錄帳號,

 

  使用pm uninstall -k com.tencent.mm卸載后安裝舊版本的微信,

  結果打開還是不行,還是提示版本過低,

 

  於是懷疑卸載的時候數據被一起刪了,根本就沒有保留,再次執行pm uninstall -k com.tencent.mm,查看data目錄,微信的目錄已經不存在了。

嘗試3、adb install -r 命令

  同樣先用新版本的把帳號登錄,然后使用 adb install -r 命令強制安裝,結果還是不行,不能安裝比當前版本低的,,,

 

 

嘗試4、替換安裝目錄

  既然用 pm uninstall -k 卸載時保留數據不行,那么就嘗試手動替換。

  首先安裝低版本的微信,把安裝目錄復制一份,然后卸載。

  再安裝新版本的微信,並登錄帳號。

  用之前保存的舊版本安裝目錄替換新版本的安裝目錄,然后重啟手機。

  重啟后提示登錄錯誤,重新輸入密碼即可,

  不知道為什么,這個手機在我寫這篇博文的時候,關於微信的頁面還是新版本的版本號,而我之前弄的另一個手機就是真實的舊版本號,

  但是這個手機系統設置中微信的版本號已經變成舊版本的了,也不影響使用。

  另一個手機的,

 

 

 

 自動化程序

   把之前替換的過程寫了個自動替換的程序,代碼如下,其中使用的ShellUtils在之前的一篇【Android手機插上usb能充電但不能識別的一種解決方法】能找到:

 
         
package com.example.wxreversion;

import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.io.File;

public class MainActivity extends AppCompatActivity
{
Handler handler;
TextView textView;


private void LogV(String s)
{
Log.v("test", s);
}

private void textAppend(final String s)
{
LogV("textAppend:" + s);
handler.post(new Runnable()
{
@Override
public void run()
{
LogV("run:" + s);

textView.setText(textView.getText() + s);
}
});
}

private String getPath()
{
String path = null;
textAppend("-----------------------------\n");


if (!ShellUtils.checkRootPermission())
{
textAppend("獲取root權限失敗,請在設置中授予權限!\n");
return path;
}

path = ShellUtils.execCommand("pm path com.tencent.mm", true).successMsg;
if (path != null)
{
try
{
path = path.substring(path.indexOf('/'), path.lastIndexOf('/'));
} catch (Throwable throwable)
{
path = null;
}
}

if (path == null)
{
textAppend("未找到微信安裝目錄,請先安裝!\n");
} else
{
textAppend("找到安裝目錄:" + path + "\n");
}

return path;
}

private boolean isEnpty(String string)
{
if (string == null || string.length() == 0)
{
return true;
}
return false;
}

private void putResult(ShellUtils.CommandResult result)
{
textAppend("返回碼:" + result.result + "\n");

if (!isEnpty(result.successMsg))
{
textAppend(result.successMsg + "\n");
} else if (!isEnpty(result.errorMsg))
{
textAppend("錯誤消息:" + result.errorMsg + "\n");
}
}

@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler = new Handler();

textView = (TextView) findViewById(R.id.textView);
textView.setMovementMethod(ScrollingMovementMethod.getInstance());

((Button) findViewById(R.id.button1)).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{

new Thread()
{
@Override
public void run()
{
String path = getPath();
if (path == null)
{
return;
}
textAppend("正在保存安裝目錄!\n");
ShellUtils.CommandResult result = ShellUtils.execCommand("cp -af " + path + " /data/local/tmp/com.tencent.mm", true);
putResult(result);
if (!isEnpty(result.errorMsg))
{
return;
}

textAppend("正在卸載微信!\n");
result = ShellUtils.execCommand("pm uninstall com.tencent.mm", true);//-k無用
putResult(result);
if (!isEnpty(result.errorMsg))
{
return;
}

textAppend("請安裝新版微信,並在登錄成功后點擊【覆蓋安裝文件並重啟】按鈕!\n");
}
}.start();

}
});


((Button) findViewById(R.id.button2)).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{

new Thread()
{
@Override
public void run()
{
String path = getPath();
if (path == null)
{
return;
}

textAppend("正在檢查是否有備份的安裝文件!\n");
if (!new File("/data/local/tmp/com.tencent.mm").exists())
{
textAppend("不存在備份的安裝文件,請先安裝低版本微信后點擊【覆蓋安裝文件並重啟】按鈕!\n");
return;
}

textAppend("已有備份的安裝文件,正在刪除當前的安裝目錄!\n");
ShellUtils.CommandResult result = ShellUtils.execCommand("rm -rf " + path + "/*", true);
putResult(result);
if (!isEnpty(result.errorMsg))
{
return;
}


textAppend("正在覆蓋安裝目錄!\n");
result = ShellUtils.execCommand("cp -af /data/local/tmp/com.tencent.mm/* " + path, true);
ShellUtils.execCommand("rm -rf /data/local/tmp/com.tencent.mm", true);
putResult(result);
if (!isEnpty(result.errorMsg))
{
return;
}

textAppend("系統將在10秒后重啟!\n");


try
{
sleep(10 * 1000);
handler.post(new Runnable()
{
@Override
public void run()
{
ShellUtils.execCommand("reboot", true);
}
});
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}.start();

}
});

textView.append("-----------------------------\n");
textView.append("該應用需要root權限!\n");
if (ShellUtils.checkRootPermission())
{
textView.append("獲取root權限成功!\n");
} else
{
textView.append("獲取root權限失敗,請在設置中授予權限!\n");
}


}
}
 
        

 

運行如下:

先安裝舊版本微信,

運行該程序,點擊左邊的【保存安裝文件並卸載】按鈕,

  安裝新版本微信並登錄,

  點擊右邊的【覆蓋安裝文件並重啟】按鈕,

  重啟后重新輸密碼登錄即可。

 

完整代碼 wxreversion.rar

安裝包在release目錄中

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM