/* * WeChat SQLCipher key hunter (Frida 17.x compatible) * Hooks CCCryptorCreate + CCCryptorCreateWithMode + CCCrypt */ var seen = {}; function captureKey(keyPtr, keyLen, label) { try { if (keyLen !== 32) return; var raw = keyPtr.readByteArray(32); if (!raw) return; var bytes = new Uint8Array(raw); // skip trivial keys (fewer than 8 unique byte values) var map = {}, n = 0; for (var i = 0; i < bytes.length; i++) { if (!map[bytes[i]]) { map[bytes[i]] = true; n++; } } if (n < 8) return; var hex = ''; for (var j = 0; j < bytes.length; j++) { hex += ('0' + bytes[j].toString(16)).slice(-2); } if (!seen[hex]) { seen[hex] = true; send({ type: 'key', hex: hex, via: label }); } } catch(e) {} } var cc1 = Module.findGlobalExportByName('CCCryptorCreate'); if (cc1) { Interceptor.attach(cc1, { onEnter: function(args) { if (args[1].toInt32() === 0) captureKey(args[3], args[4].toInt32(), 'CCCryptorCreate'); }}); } var cc2 = Module.findGlobalExportByName('CCCryptorCreateWithMode'); if (cc2) { Interceptor.attach(cc2, { onEnter: function(args) { if (args[2].toInt32() === 0) captureKey(args[5], args[6].toInt32(), 'CCCryptorCreateWithMode'); }}); } var cc3 = Module.findGlobalExportByName('CCCrypt'); if (cc3) { Interceptor.attach(cc3, { onEnter: function(args) { if (args[1].toInt32() === 0) captureKey(args[3], args[4].toInt32(), 'CCCrypt'); }}); } send({ type: 'ready', cc1: !!cc1, cc2: !!cc2, cc3: !!cc3 });