相信每个人的微信通信录里都存在一些 「 僵尸粉 」 ,他们默默地躺在联系人列表中,你以为对方还是朋友,那就真是太年轻、太天真的;实际上,对方早就把从好友列表中删了,那如何来筛选出这群人呢?
本篇文章的目的是自动化操作微信 App,通过 「 模拟给好友转账 」 来筛选出所有的僵尸粉,并一键删除它们。
在开始编写脚本之前,需要做好如下准备工作
- 一部 Root 后的 Android 手机或者模拟器,如果没有 Root 的设备,推荐使用网易 MuMu 模拟器
- Android 开发环境、Android Studio
- sqlcipher 图形化工具
- 自动化工具:Python 虚拟环境下安装 pocoui
'''
更多Python学习资料以及源码教程资料,可以在群1136201545免费获取
'''
编 写 脚 本
第 1 步,我们需要破解微信 App 的数据库。
//微信 App 的目录
public static final String WX_ROOT_PATH = "/data/data/com.tencent.mm/";
/**
* 执行linux指令
*
* @param paramString
*/
public static void execRootCmd(String paramString)
{
try
{
Process localProcess = Runtime.getRuntime().exec("su");
Object localObject = localProcess.getOutputStream();
DataOutputStream localDataOutputStream = new DataOutputStream((OutputStream) localObject);
String str = String.valueOf(paramString);
localObject = str + "
";
localDataOutputStream.writeBytes((String) localObject);
localDataOutputStream.flush();
localDataOutputStream.writeBytes("exit
");
localDataOutputStream.flush();
localProcess.waitFor();
localObject = localProcess.exitValue();
} catch (Exception localException)
{
localException.printStackTrace();
}
}
//获取权限
RootUtils.execRootCmd("chmod 777 -R " + WX_ROOT_PATH);
然后,获取微信数据库的密码。
微信数据库的密码是由设备的 imei 和微信的 uid 进过 md5 算法生成的。
/**
* 根据imei和uin生成的md5码,获取数据库的密码(去前七位的小写字母)
*
* @param imei
* @param uin
* @return
*/
public static String getDbPassword(String imei, String uin)
{
if (TextUtils.isEmpty(imei) || TextUtils.isEmpty(uin))
{
Log.d("xag", "初始化数据库密码失败:imei或uid为空");
return "密码错误";
}
String md5 = MD5Utils.md5(imei + uin);
assert md5 != null;
return md5.substring(0, 7).toLowerCase();
}
接着,就可以使用 SQLCipher 依赖库来对微信数据库进行查询,我们需要为项目添加如下依赖,方便操作数据库。
//我们需要对项目增加依赖
implementation 'net.zetetic:android-database-sqlcipher:3.5.4@aar'
利用上面得到的密码打开加密数据库,然后查询「rcontact」表获取微信通讯录内所有的好友的微信号、昵称、用户名等数据。
/**
* 连接数据库
*
* 常用库介绍:【rcontact】联系人表,【message】聊天消息表
*
* @param dbFile
*/
private void openWxDb(File dbFile, String db_pwd)
{
//所有联系人
List contacts = new ArrayList();
SQLiteDatabase.loadLibs(this);
SQLiteDatabaseHook hook = new SQLiteDatabaseHook()
{
public void preKey(SQLiteDatabase database)
{
}
public void postKey(SQLiteDatabase database)
{
atabase.rawExecSQL("PRAGMA cipher_migrate;"); //兼容2.0的数据库
}
};
try
{
//打开数据库连接
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbFile, db_pwd, null, hook);
//查询所有联系人
//过滤掉本人、群聊、公众号、服务号等一些联系人
//verifyFlag != 0:公众号、服务号
//注意黑名单用户,我-设置-隐私-通讯录黑名单
Cursor c1 = db.rawQuery(
"select * from rcontact where verifyFlag =0 and type not in (2,4,8,9,33,35,256,258,512,2051,32768,32770,32776,33024,65536,65792,98304) and username not like "%@app" and username not like "%@qqim" and username not like "%@chatroom" and encryptUsername!=""",
null);
while (c1.moveToNext())
{
String userName = c1.getString(c1.getColumnIndex("username"));
String alias = c1.getString(c1.getColumnIndex("alias"));
String nickName = c1.getString(c1.getColumnIndex("nickname"));
int type = c1.getInt(c1.getColumnIndex("type"));
contacts.add(new Contact(userName, alias, nickName));
}
Log.d("xag", "微信通讯录中,联系人数目:" + contacts.size() + "个");
for (int i = 0; i
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?