由于微信的数据db文件进行加密操作所以咱们这边需要解密
获取手机序列号IMEI号,
public static String getIMEI(Context context) { TelephonyManager manager = (TelephonyManager) context.getSystemService(TELEPHONY_SERVICE); if (manager.getDeviceId() != null && manager.getDeviceId().length() > 0) { return manager.getDeviceId(); } else { return ""; } }
获取微信用户信息号需要解析xml,这里解析xml用到的是XmlPullParser进行解析的
这里path路径是:/data/data/com.tencent.mm/shared_prefs/system_config_prefs.xml
public static String getUin(String path) { try { FileInputStream inputStream = new FileInputStream(new File(path)); XmlPullParser parser = Xml.newPullParser(); parser.setInput(inputStream, "UTF-8"); int eventType = parser.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { switch (eventType) { case XmlPullParser.START_DOCUMENT: break; case XmlPullParser.START_TAG: String tagName = parser.getName(); if ("int".equals(parser.getName())) { String name = parser.getAttributeValue(0); String value = parser.getAttributeValue(1); Log.e("int", "name:" + name + ",value:" + value); return value; } break; case XmlPullParser.END_TAG: break; case XmlPullParser.END_DOCUMENT: break; } eventType = parser.next(); } } catch (FileNotFoundException e) { Log.e("FileNotFoundException:", e.toString()); } catch (XmlPullParserException e) { Log.e("XmlPullParserException:", e.toString()); } catch (IOException e) { e.printStackTrace(); } return ""; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
有上面两个字符串计算出打开db的密码,
这里的计算需要用到md5算法进行计算操作先把md5这段代码贴出来
计算密码调用与这几段代码进行配合
String password= (MD5Util.md5(XmlUtil.getIMEI(context)+XmlUtil.getUin("/data/data/com.tencent.mm/shared_prefs/system_config_prefs.xml"))).substring(0,7).toLowerCase()
import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;/** * author: * date: 2016/10/25 20:59 */public class MD5Util { public static final char HEX_DIGITS[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; public static String toHexString(byte[] b) { StringBuilder sb = new StringBuilder(b.length * 2); for (int i = 0; i < b.length; i++) { sb.append(HEX_DIGITS[(b[i] & 0xf0) >>> 4]); sb.append(HEX_DIGITS[b[i] & 0x0f]); } return sb.toString(); } public static String md5(String s) { try { MessageDigest digest = java.security.MessageDigest.getInstance("MD5"); digest.update(s.getBytes()); byte messageDigest[] = digest.digest(); return toHexString(messageDigest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
拿到密码后可以对数据库的读写进行操作
import android.content.Context;import android.text.TextUtils;import android.util.Log;import android.widget.Toast;import net.sqlcipher.Cursor;import net.sqlcipher.database.SQLiteDatabase;import net.sqlcipher.database.SQLiteDatabaseHook;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;/** * Created by zxf on 2016/10/25. */public class DataHelp { /** * 操作数据库读取微信消息 * @param context * @param path */ public static void readWeChatDatabase(Context context,String path) { SQLiteDatabase.loadLibs(context); String password= (MD5Util.md5(XmlUtil.getIMEI(context)+XmlUtil.getUin(Constants.uinPath))).substring(0,7).toLowerCase(); Log.e("password", "password:"+password ); SQLiteDatabaseHook hook = new SQLiteDatabaseHook(){ public void preKey(SQLiteDatabase database){ } public void postKey(SQLiteDatabase database){ database.rawExecSQL("PRAGMA cipher_migrate;"); } }; try { long time=System.currentTimeMillis(); SQLiteDatabase db = SQLiteDatabase.openDatabase(path, password, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS, hook); long time2=System.currentTimeMillis(); long time_1=time2-time; Toast.makeText(context,"time_3:"+time_1, Toast.LENGTH_SHORT).show(); Log.e("readWeChatDatabase", "time_3:"+time_1 ); int count=0; Cursor c = db.rawQuery("select * from message" , null); while (c.moveToNext()) { int _id = c.getInt(c.getColumnIndex("msgId")); String content= c.getString(c.getColumnIndex("content")); count++; Log.e("readWeChatDatabase", "content:"+content ); } c.close(); db.close(); long time_2=System.currentTimeMillis()-time2; Toast.makeText(context,"time_4:"+time_2+",count:"+count , Toast.LENGTH_SHORT).show(); Log.e("readWeChatDatabase", "time_4:"+time_2+",count:"+count ); } catch (Exception e) { Log.e("e", "readWeChatDatabase: "+e.toString() ); } } /** * 复制单个文件 * @param oldPath String 原文件路径 如:c:/fqf.txt * @param newPath String 复制后路径 如:f:/fqf.txt * @return boolean */ public static void copyFile(Context context,String oldPath, String newPath) { long time=System.currentTimeMillis(); deleteFolderFile(newPath,true); long time2=System.currentTimeMillis(); long time_1=time2-time; Log.e("copyFile", "time_1:"+time_1 ); InputStream inStream=null; FileOutputStream fs=null; try { int bytesum = 0; int byteread = 0; File oldfile = new File(oldPath); if (oldfile.exists()) { inStream = new FileInputStream(oldPath); fs = new FileOutputStream(newPath); byte[] buffer = new byte[2048]; while ( (byteread = inStream.read(buffer)) != -1) { bytesum += byteread; fs.write(buffer, 0, byteread); } long time_2=System.currentTimeMillis()-time2; Log.e("copyFile", "time_2:"+time_2); readWeChatDatabase(context,newPath); } }catch (Exception e) { System.out.println("复制单个文件操作出错"); e.printStackTrace(); }finally { try { if (inStream!=null) { inStream.close(); } if (fs!=null){ fs.close(); } } catch (IOException e) { e.printStackTrace(); } } } /** * 删除指定目录下文件及目录 * * @param deleteThisPath * @return */ public static void deleteFolderFile(String filePath, boolean deleteThisPath) { if (!TextUtils.isEmpty(filePath)) { try { File file = new File(filePath); if (file.isDirectory()) { File files[] = file.listFiles(); for (int i = 0; i < files.length; i++) { deleteFolderFile(files[i].getAbsolutePath(), true); } } if (deleteThisPath) { if (!file.isDirectory()) { file.delete(); } else { if (file.listFiles().length == 0) { file.delete(); } } } } catch (Exception e) { e.printStackTrace(); } } }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
在初始activity调用
import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import com.xilexuan.wechatcrack.util.DataHelp;import java.util.Timer;import java.util.TimerTask;public class MainActivity extends AppCompatActivity { Timer timer; TimerTask mTimerTask; @Override protected void onCreate(Bundle savedInstanceState) { timer = new Timer(); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final String old_path="/data/data/com.tencent.mm/MicroMsg/b93e23895b9f5b4a8d781ba8d702cfe8/EnMicroMsg.db"; final String new_path="/data/data/copy到你的文件夹下比如com...../EnMicroMsg.db"; DataHelp.copyFile(this,old_path,new_path); mTimerTask =new TimerTask() { @Override public void run() { runOnUiThread(new Runnable() { @Override public void run() { DataHelp.copyFile(MainActivity.this,old_path,new_path); } }); } }; timer.schedule(mTimerTask, 0, 10000); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
最后在log内就能看到你截取到的微信聊天记录,这里设置的10秒获取一次。
------------------------------------------------------------------------------
个人简介:
花名:nexttake
精通Android NDK 与 SDK开发,熟悉Java服务器端技术,对新技术有热情,有较强的源码分析能力 。希望和大家一起分享技术,
技术交流群 171740554