I am myself a C# developer, and I am interested in interfacing with my phone through USB, but without using ADB command lines.
Is there any project going on what's goal is to create a C# interface for Android phones?
Mostly data management, like file browsing, and such things, and of course sync, the reboot options, device listing and resolving, application management, and so on.
Hi,
If you want, you can use the DroidExplorer source code. Take a look in the namespace DroidExplorer.Core.Adb
That's what I did, but it "just" binds the adb executable with all the commands, while I am looking for a pure C# solution, without involving adb.exe!
fonix232 said:
That's what I did, but it "just" binds the adb executable with all the commands, while I am looking for a pure C# solution, without involving adb.exe!
Click to expand...
Click to collapse
Are you sure ?
Take a look in the class DroidExplorer.Core.Adb.AdbHelper. This class only use pure sockets
Code:
public Socket Open ( IPAddress address, IDevice device, int port ) {
Socket s = new Socket ( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
try {
s.Connect ( address, port );
s.Blocking = true;
s.NoDelay = false;
SetDevice ( s, device );
byte[] req = CreateAdbForwardRequest ( null, port );
if ( !Write ( s, req ) ) {
throw new IOException ( "failed submitting request to ADB" );
}
AdbResponse resp = ReadAdbResponse ( s, false );
if ( !resp.Okay ) {
throw new IOException ( "connection request rejected" );
}
s.Blocking = true;
} catch ( IOException ) {
s.Close ( );
throw;
}
return s;
}
Yes, uses pure sockets to connect to Adb.
Take a look:
Code:
public int GetAdbVersion ( IPEndPoint address ) {
byte[] request = FormAdbRequest ( "host:version" );
byte[] reply;
Socket adbChan = new Socket ( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
try {
adbChan.Connect ( address );
adbChan.Blocking = true;
if ( !Write ( adbChan, request ) )
throw new IOException ( "failed asking for adb version" );
AdbResponse resp = ReadAdbResponse ( adbChan, false /* readDiagString */);
if ( !resp.IOSuccess || !resp.Okay ) {
this.LogError ( "Got timeout or unhappy response from ADB fb req: " + resp.Message );
adbChan.Close ( );
return -1;
}
reply = new byte[4];
if ( !Read ( adbChan, reply ) ) {
this.LogError ( "error in getting data length" );
adbChan.Close ( );
return -1;
}
String lenHex = Encoding.Default.GetString ( reply );
int len = int.Parse ( lenHex, System.Globalization.NumberStyles.HexNumber );
// the protocol version.
reply = new byte[len];
if ( !Read ( adbChan, reply ) ) {
this.LogError ( "did not get the version info" );
adbChan.Close ( );
return -1;
}
String sReply = Encoding.Default.GetString ( reply );
return int.Parse ( sReply, System.Globalization.NumberStyles.HexNumber );
} catch ( Exception ex ) {
Console.WriteLine ( ex );
throw;
}
}
The adbChan socket is used to connect to ADB over TCP. Also there are listeners for ADB responses, and a forwarder to send ADB commands.
Error while flashing
message send failed.
Nokia.connectivity.messaging.messagingsendexception: Message send failed. ---> nokia.connectivity.messaging.capi.capimessagingexception: Tcssend failed with error
code: -2080331756
at nokia.connectivity.messaging.capi.capimessagestream.checkreturnvalue(string methodname, uint32 returnvalue)
at nokia.connectivity.messaging.capi.capimessagestream.send(uint32 cookie, byte[] data, uint32 datatype, uint32 itemcount, uint32 timeout, intptr eventt,
sendcallback onsentcallback, intptr paramz)
at nokia.connectivity.messaging.handlers.messagehandler.send(uint32 cookie, sendparameters sparams)
--- end of inner exception stack trace ---
at nokia.connectivity.messaging.handlers.messagehandler.send(uint32 cookie, sendparameters sparams)
at nokia.connectivity.messaging.messagestream.send(message message)
at nokia.murzim.connectivity.fuseadaptation.murzimfusemessaging.send(byte[] request, timespan timespan)
at nokia.murzim.uefi.flashapp.coreprogrammeradaptation.messaging.waitforresponse(imessagewrapper request, imessagewrapper& response)
at nokia.murzim.uefi.flashapp.coreprogrammeradaptation.messaging.sendandreceive(imessagewrapper messagetosend, imessagewrapper response)
at coreprogrammer.programmer.onsendandreceive(imessage* message, imessage* response)
at nativemessaging.sendandreceive(nativemessaging* , imessage* message, imessage* response)
at wp8programmer.handshakeuefi(wp8programmer* )
at wp8programmer.programsignedffufile(wp8programmer* , basic_string<char\,std::char_traits<char>\,std::allocator<char> >* path, basic_string<char
\,std::char_traits<char>\,std::allocator<char> >* options)
at coreprogrammer.programmer.programsignedffufile(string path, string options, string& lasterror)
at nokia.murzim.uefi.flashapp.coreprogrammeradaptation.programmeradaptation.programsignedffu(string file, string options)
at nokia.murzim.uefi.flashapp.murzimflashapp.program(string file, boolean skipwrite, boolean skiphash, boolean skipidcheck, boolean skipsignaturecheck, boolean
verifywrite, boolean eraseuserarea)
at nokia.caresuite.plugins.murzimrecovery.recoverydialog.recoverydialogmodel.flash()
at nokia.caresuite.plugins.murzimrecovery.recoverydialog.recoverydialogmodel.<handledownloadvariantpackagecompleted>b__8(object state)
Click to expand...
Click to collapse
hello,
i open this thread to collect informations about a common problem that happens after flashing new roms
this thread has generic purpose, and is not intended for a specific board...
- suggestions on how to discover the cause of the problem
- suggestions on how to fix the problem
anyone that think to have some useful informations on this issue can insert his post
i am not an expert ( and still my wifi is not working )
but i collected some informations, and i would like to share them
The first thing is:
what happens when from the settings i click on wifi to turn it on
to see this, i opened a terminal emulator session
and i have written this:
adb logcat > 'some file name on a writable directory' (for example , i redirected the output to the external sd card)
here is what was written on the file (extracting from the file only the last part, that is the output related to my action of wifi activation):
D/WifiHW ( 368): Read wifi chip type OK ! wifi_chip_type = RK901
D/WifiHW ( 368): wifi_load_driver: DRIVER_MODULE_PATH = /system/lib/modules/rkwifi.ko, DRIVER_MODULE_ARG =
D/BluetoothAdapterService(1097373104)( 811): getState(): mAdapterProperties: [email protected] 4168aef0
D/BluetoothAdapterService(1097373104)( 811): getState(): mAdapterProperties: [email protected] 4168aef0
D/WifiService( 368): setWifiEnabled: true pid=870, uid=1000
D/AudioHardwareALSA( 109): Audio exiting sandby will open audio device
D/AudioHardwareALSA( 109): AudioStreamOutALSA::standby().....
D/WifiHW ( 368): wifi_load_driver: driver load failed
D/WifiHW ( 368): Unable to unload driver module "wlan": No such file or directory
E/WifiStateMachine( 368): Failed to load driver!
E/WifiStateMachine( 368): DriverFailedState
Searching on the web this string: "Read wifi chip type OK ! wifi_chip_type"
i found this:
https://github.com/aloksinha2001/pi****u-3.0.8-alok/blob/master/RK30_MT5931_MT6622/wifi/wifi.c
into procedure check_wifi_chip_type() i saw exactly this part:
else if (0 == strncmp(buf, "RK901", strlen("RK901")) )
{
wifi_chip_type = RK901;
ALOGD("Read wifi chip type OK ! wifi_chip_type = RK901");
}
here is compared the value of string buf with "RK901"
the string buf is read from this file: "/sys/class/rkwifi/chip"
(so i suppose that this file has been written before by some other procedure)
so, i searched the caller procedure of check_wifi_chip_type():
in the same source i find this caller:
int wifi_load_driver()
{
#ifdef WIFI_DRIVER_MODULE_PATH
char driver_status[PROPERTY_VALUE_MAX];
int count = 100; /* wait at most 20 seconds for completion */
int type;
char path[64];
if (is_wifi_driver_loaded()) {
return 0;
}
strcpy(path, DRIVER_MODULE_PATH);
type = check_wifi_chip_type();
if((type == RK901) || (type == RK903) || (type == BCM4330)) {
strcpy(path, "/system/lib/modules/rkwifi.ko");
} else if (type == RTL8188CU) {
....
this procedure as first step checks if the driver is already loaded,
if not:
the driver module path is set by default to "/system/lib/modules/wlan.ko"
Then basing on the chip type is got a more specific path:
for example, for RK901/RK903/BCM4330 the path is set to : "/system/lib/modules/rkwifi.ko"
Then, is checked if the file does exist, and if not the path is seth to the default DRIVER_MODULE_PATH,
that is "/system/lib/modules/wlan.ko"
// judge if the KO file exist, if not, insmod wlan.ko
if (access(path, F_OK) < 0) {
ALOGD("DRIVER_MODULE_PATH = %s (Not such file)...", path);
strcpy(path, DRIVER_MODULE_PATH);
}
Then,
is called insmod (insert module),
to load the driver file in 'memory' (a new module into the kernel, i suppose):
if (insmod(path, DRIVER_MODULE_ARG) < 0) {
ALOGD("%s: driver load failed", __FUNCTION__);
wifi_unload_driver();
if(retry_count-- > 0) goto retry_load_driver;
return -1;
}
Looking the logcat above,
the flow in my case stops here, with : wifi_load_driver: driver load failed
so something happened in insmod:it is not able to load the file /system/lib/modules/rkwifi.ko in memory or initialize it
(the file is found, else the process should stop before, when checking access to the file)
The insmod function does this:
allocates memory for the structure name (type utsname) :
memset(&name, 0, sizeof(name));
and load the file on this area:
module = load_file(filename_release, &size);
Then is checked if the file has been loaded
if (!module)
return -1;
and finally
the module is 'initialized':
ret = init_module(module, size, args);
One of this two events went wrong, because insmod returned -1
My investigation stops here... i am not able to proceed more...
but i am open to all suggestions and hints
Thank you!!
Vicolodo said:
The first thing is:
what happens when from the settings i click on wifi to turn it on
to see this, i opened a terminal emulator session
and i have written this:
adb logcat > 'some file name on a writable directory' (for example , i redirected the output to the external sd card)
here is what was written on the file (extracting from the file only the last part, that is the output related to my action of wifi activation):
D/WifiHW ( 368): Read wifi chip type OK ! wifi_chip_type = RK901
D/WifiHW ( 368): wifi_load_driver: DRIVER_MODULE_PATH = /system/lib/modules/rkwifi.ko, DRIVER_MODULE_ARG =
D/BluetoothAdapterService(1097373104)( 811): getState(): mAdapterProperties: [email protected] 4168aef0
D/BluetoothAdapterService(1097373104)( 811): getState(): mAdapterProperties: [email protected] 4168aef0
D/WifiService( 368): setWifiEnabled: true pid=870, uid=1000
D/AudioHardwareALSA( 109): Audio exiting sandby will open audio device
D/AudioHardwareALSA( 109): AudioStreamOutALSA::standby().....
D/WifiHW ( 368): wifi_load_driver: driver load failed
D/WifiHW ( 368): Unable to unload driver module "wlan": No such file or directory
E/WifiStateMachine( 368): Failed to load driver!
E/WifiStateMachine( 368): DriverFailedState
Searching on the web this string: "Read wifi chip type OK ! wifi_chip_type"
i found this:
https://github.com/aloksinha2001/pi****u-3.0.8-alok/blob/master/RK30_MT5931_MT6622/wifi/wifi.c
into procedure check_wifi_chip_type() i saw exactly this part:
else if (0 == strncmp(buf, "RK901", strlen("RK901")) )
{
wifi_chip_type = RK901;
ALOGD("Read wifi chip type OK ! wifi_chip_type = RK901");
}
here is compared the value of string buf with "RK901"
the string buf is read from this file: "/sys/class/rkwifi/chip"
(so i suppose that this file has been written before by some other procedure)
so, i searched the caller procedure of check_wifi_chip_type():
in the same source i find this caller:
int wifi_load_driver()
{
#ifdef WIFI_DRIVER_MODULE_PATH
char driver_status[PROPERTY_VALUE_MAX];
int count = 100; /* wait at most 20 seconds for completion */
int type;
char path[64];
if (is_wifi_driver_loaded()) {
return 0;
}
strcpy(path, DRIVER_MODULE_PATH);
type = check_wifi_chip_type();
if((type == RK901) || (type == RK903) || (type == BCM4330)) {
strcpy(path, "/system/lib/modules/rkwifi.ko");
} else if (type == RTL8188CU) {
....
this procedure as first step checks if the driver is already loaded,
if not:
the driver module path is set by default to "/system/lib/modules/wlan.ko"
Then basing on the chip type is got a more specific path:
for example, for RK901/RK903/BCM4330 the path is set to : "/system/lib/modules/rkwifi.ko"
Then, is checked if the file does exist, and if not the path is seth to the default DRIVER_MODULE_PATH,
that is "/system/lib/modules/wlan.ko"
// judge if the KO file exist, if not, insmod wlan.ko
if (access(path, F_OK) < 0) {
ALOGD("DRIVER_MODULE_PATH = %s (Not such file)...", path);
strcpy(path, DRIVER_MODULE_PATH);
}
Then,
is called insmod (insert module),
to load the driver file in 'memory' (a new module into the kernel, i suppose):
if (insmod(path, DRIVER_MODULE_ARG) < 0) {
ALOGD("%s: driver load failed", __FUNCTION__);
wifi_unload_driver();
if(retry_count-- > 0) goto retry_load_driver;
return -1;
}
Looking the logcat above,
the flow in my case stops here, with : wifi_load_driver: driver load failed
so something happened in insmod:it is not able to load the file /system/lib/modules/rkwifi.ko in memory or initialize it
(the file is found, else the process should stop before, when checking access to the file)
The insmod function does this:
allocates memory for the structure name (type utsname) :
memset(&name, 0, sizeof(name));
and load the file on this area:
module = load_file(filename_release, &size);
Then is checked if the file has been loaded
if (!module)
return -1;
and finally
the module is 'initialized':
ret = init_module(module, size, args);
One of this two events went wrong, because insmod returned -1
My investigation stops here... i am not able to proceed more...
but i am open to all suggestions and hints
Thank you!!
Click to expand...
Click to collapse
Interesting... Yesterday i was trying to solve this problem caused by a cwm recovery flashing during about 8 hours with my mk809ii. I let my pc downloading about 10 different roms from other similar devices, and this morning i stay to try one by one. Finally i found "mk808B bob finless 2.1 room (jb4.2.2) with wifi APxxxx" (APxxxx is my wifi chip, i can't remember the xxxx just now) fix both wifi and bluetooth.
You did a good research, i will save your post on case i get the error again, but i think the best thing to do is to search for a compatible rom and try, with same both cpu and wifi chipset. Also now after read your post i am going to save a backup of system /lib and system /etc directories, maybe changing the wifi library files fix the error without needing of flash and reflash...
Thanks, i liked your post!
Enviado desde mi GT-P7510 usando Tapatalk 2
I will just leave this here. :good:
Python:
Code:
#!/usr/bin/env python
""" decrypt12.py: Decrypts WhatsApp msgstore.db.crypt12 files. """
""" Requires pycrypto and pycryptodome packages. """
__author__ = 'TripCode'
__copyright__ = 'Copyright (C) 2016'
__license__ = 'GPLv3'
__status__ = 'Production'
__version__ = '1.0'
from Crypto.Cipher import AES
import os
import sys
import zlib
def keyfile(kf):
global t1, key
if os.path.isfile(kf) == False:
quit('The specified input key file does not exist.')
elif os.path.getsize(kf) != 158:
quit('The specified input key file is invalid.')
with open(kf, 'rb') as keyfile:
keyfile.seek(30)
t1 = keyfile.read(32)
keyfile.seek(126)
key = keyfile.read(32)
return True
def decrypt12(cf, of):
global t2, iv
if os.path.isfile(cf) == False:
quit('The specified input crypt12 file does not exist.')
tf = cf+'.tmp'
with open(cf, 'rb') as crypt12:
crypt12.seek(3)
t2 = crypt12.read(32)
if t1 != t2:
quit('Key file mismatch or crypt12 file is corrupt.')
crypt12.seek(51)
iv = crypt12.read(16)
crypt12.seek(67)
primer(tf, crypt12, 20)
cipher = AES.new(key, AES.MODE_GCM, iv)
sqlite = zlib.decompress(cipher.decrypt(open(tf, 'rb').read()))
with open(of, 'wb') as msgstore:
msgstore.write(sqlite)
msgstore.close()
os.remove(tf)
return True
def primer(tf, crypt12, sb):
with open(tf, 'wb') as header:
header.write(crypt12.read())
header.close()
with open(tf, 'rb+') as footer:
footer.seek(-sb, os.SEEK_END)
footer.truncate()
footer.close()
def validate(ms):
with open(ms, 'rb') as msgstore:
if msgstore.read(6).decode('ascii').lower() != 'sqlite':
os.remove(ms)
msg = 'Decryption of crypt12 file has failed.'
else:
msg = 'Decryption of crypt12 file was successful.'
msgstore.close()
quit(msg)
def main():
if len(sys.argv) > 2 and len(sys.argv) < 5:
if len(sys.argv) == 3:
outfile = 'msgstore.db'
else:
outfile = sys.argv[3]
if keyfile(sys.argv[1]) and decrypt12(sys.argv[2], outfile):
validate(outfile)
else:
print('\nWhatsApp Crypt12 Database Decrypter '+__version__+' '+__copyright__+' by '+__author__+'\n')
print('\tUsage: python '+str(sys.argv[0])+' key msgstore.db.crypt12 msgstore.db\n')
if __name__ == "__main__":
main()
Code:
Usage: python decrypt12.py key msgstore.db.crypt12 msgstore.db
Java:
Code:
package decrypt12;
/*
*
*** decrypt12.jar: Decrypts WhatsApp msgstore.db.crypt12 files. ***
*
* Author : TripCode
* Copyright : Copyright (C) 2016
* License : GPLv3
* Status : Production
* Version : 1.0
*
*/
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.security.Security;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
// import org.spongycastle.jce.provider.BouncyCastleProvider; // Android
public class decrypt12 {
static {
Security.insertProviderAt(new org.bouncycastle.jce.provider.BouncyCastleProvider(), 1);
// Security.insertProviderAt(new org.spongycastle.jce.provider.BouncyCastleProvider(), 1); // Android
}
public static void decrypt(String KeyFile, String C12File, String SQLFile) throws Exception {
final File tempFile = new File(System.getProperty("java.io.tmpdir") + "/"
+ (int) (System.currentTimeMillis() / 1000L) + "-msgstore.enc");
if (!new File(KeyFile).isFile())
quit("The specified input key file does not exist.");
else if (new File(KeyFile).length() != 158)
quit("The specified input key file is invalid.");
else if (!new File(C12File).isFile())
quit("The specified input crypt12 file does not exist.");
InputStream KeyIn = new FileInputStream(KeyFile);
InputStream WdbIn = new BufferedInputStream(new FileInputStream(C12File));
byte[] KeyData = new byte[158];
KeyIn.read(KeyData);
byte[] T1 = new byte[32];
System.arraycopy(KeyData, 30, T1, 0, 32);
byte[] KEY = new byte[32];
System.arraycopy(KeyData, 126, KEY, 0, 32);
KeyIn.close();
byte[] C12Data = new byte[67];
WdbIn.read(C12Data);
byte[] T2 = new byte[32];
System.arraycopy(C12Data, 3, T2, 0, 32);
byte[] IV = new byte[16];
System.arraycopy(C12Data, 51, IV, 0, 16);
if (!new String(T1, 0, T1.length, "ASCII").equals(new String(T2, 0, T2.length, "ASCII")))
quit("Key file mismatch or crypt12 file is corrupt.");
int InputLength = WdbIn.available();
RandomAccessFile raf = new RandomAccessFile(tempFile, "rw");
byte[] tempBuffer = new byte[1024];
int I;
while ((I = WdbIn.read(tempBuffer)) != -1)
raf.write(tempBuffer, 0, I);
raf.setLength(InputLength - 20);
raf.close();
WdbIn.close();
InputStream PdbSt = new BufferedInputStream(new FileInputStream(tempFile));
Cipher cipher;
Security.addProvider(new BouncyCastleProvider());
cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC"); // BouncyCastle
// cipher = Cipher.getInstance("AES/GCM/NoPadding", "SC"); // SpongyCastle (Android)
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(KEY, "AES"), new IvParameterSpec(IV));
CipherInputStream CipherStream = new CipherInputStream(PdbSt, cipher);
InflaterInputStream CryptOutput = new InflaterInputStream(CipherStream, new Inflater(false));
try {
FileOutputStream InflateBuffer = new FileOutputStream(SQLFile);
int N = 0;
byte[] CryptBuffer = new byte[8192];
while ((N = CryptOutput.read(CryptBuffer)) != -1) {
InflateBuffer.write(CryptBuffer, 0, N);
}
InflateBuffer.close();
} catch (IOException ex) {
quit("Fatal error:" + ex);
}
CipherStream.close();
tempFile.delete();
InputStream SqlDB = new FileInputStream(SQLFile);
byte[] SqlData = new byte[6];
SqlDB.read(SqlData);
byte[] MS = new byte[6];
System.arraycopy(SqlData, 0, MS, 0, 6);
SqlDB.close();
if (!new String(MS, 0, MS.length, "ASCII").toLowerCase().equals("sqlite")) {
new File(SQLFile).delete();
quit("Decryption of crypt12 file has failed.");
}
else
quit("Decryption of crypt12 file was successful.");
}
private static void quit(String Msg) {
System.out.println(Msg);
System.exit(0);
}
public static void main(String[] args) throws Exception {
String outFile;
if (args.length > 1 && args.length < 4) {
if (args.length == 3)
outFile = args[2];
else
outFile = "msgstore.db";
decrypt(args[0], args[1], outFile);
} else {
System.out.println("\nWhatsApp Crypt12 Database Decrypter 1.0 Copyright (C) 2016 by TripCode");
System.out.println("\tUsage: java -jar decrypt12.jar key msgstore.db.crypt12 msgstore.db\n");
}
}
}
Code:
Usage: java -jar decrypt12.jar key msgstore.db.crypt12 msgstore.db
GitHub Repository: WhatsApp-Crypt12-Decrypter
Just a quick question: My phone was swapped by a repair shop and the other person who got my phone didn't realize this at first. She did a factory reset, and probably installed Whatsapp with her SIM card before I got my phone back. I'm so angry right now...
I guess my key file is gone - either deleted by the factory reset or overwritten with her Whatsapp's key file. I have several backups of the Whatsapp directory and still the same Google account, IMEI and phone number. Can I restore my messages or are any attempts futile?
(I see that the code asks for a key file, so if I cannot get it/extract it somewhere, there is probably no chance anymore?)
hi, realy great tool
with that i could open the msgstore.db and see my chats
but is it possible to convert this file into a .db.crypt12 file or something like that, so i can open it with whatsapp an have my chats back?
or are there other ways, i can use this msgstore.db + wa.db to recover the chats?
Hi!
I have a crypt12 database but no key...is there anyone out there able to decrypt it?
How much will it cost to me to do this? Can anyone do it for me?
Is the code written here above working in decrypting a crypt12 database?
I don't want to root or install any spyware, just trying to decrypt the file.
anyone interested in trying?
Please write dawn here if you're interested and we'll get in contact...
ettorebonfanti said:
Hi!
I have a crypt12 database but no key...is there anyone out there able to decrypt it?
How much will it cost to me to do this? Can anyone do it for me?
Is the code written here above working in decrypting a crypt12 database?
I don't want to root or install any spyware, just trying to decrypt the file.
anyone interested in trying?
Please write dawn here if you're interested and we'll get in contact...
Click to expand...
Click to collapse
There is a program out there which claims to obtain the key file without root. If it's still working today, I don't know. Here: https://forum.xda-developers.com/showthread.php?t=2770982
If you want the key file, it's better to root your phone and get it. It's not that hard. You can even unroot your phone after catching the key.
And no, someone can't just decrypt the database, because the key is there for a reason, and this reason is security.
Excellent! Just used this to fix a Whatapp DB.
---------- Post added at 10:57 AM ---------- Previous post was at 10:50 AM ----------
This is great thanks! How do I encrypt the database again with crypt12?
I have both, the DB and the key.
TripCode said:
I will just leave this here. :good:
Python:
Code:
#!/usr/bin/env python
""" decrypt12.py: Decrypts WhatsApp msgstore.db.crypt12 files. """
""" Requires pycrypto and pycryptodome packages. """
__author__ = 'TripCode'
__copyright__ = 'Copyright (C) 2016'
__license__ = 'GPLv3'
__status__ = 'Production'
__version__ = '1.0'
from Crypto.Cipher import AES
import os
import sys
import zlib
def keyfile(kf):
global t1, key
if os.path.isfile(kf) == False:
quit('The specified input key file does not exist.')
elif os.path.getsize(kf) != 158:
quit('The specified input key file is invalid.')
with open(kf, 'rb') as keyfile:
keyfile.seek(30)
t1 = keyfile.read(32)
keyfile.seek(126)
key = keyfile.read(32)
return True
def decrypt12(cf, of):
global t2, iv
if os.path.isfile(cf) == False:
quit('The specified input crypt12 file does not exist.')
tf = cf+'.tmp'
with open(cf, 'rb') as crypt12:
crypt12.seek(3)
t2 = crypt12.read(32)
if t1 != t2:
quit('Key file mismatch or crypt12 file is corrupt.')
crypt12.seek(51)
iv = crypt12.read(16)
crypt12.seek(67)
primer(tf, crypt12, 20)
cipher = AES.new(key, AES.MODE_GCM, iv)
sqlite = zlib.decompress(cipher.decrypt(open(tf, 'rb').read()))
with open(of, 'wb') as msgstore:
msgstore.write(sqlite)
msgstore.close()
os.remove(tf)
return True
def primer(tf, crypt12, sb):
with open(tf, 'wb') as header:
header.write(crypt12.read())
header.close()
with open(tf, 'rb+') as footer:
footer.seek(-sb, os.SEEK_END)
footer.truncate()
footer.close()
def validate(ms):
with open(ms, 'rb') as msgstore:
if msgstore.read(6).decode('ascii').lower() != 'sqlite':
os.remove(ms)
msg = 'Decryption of crypt12 file has failed.'
else:
msg = 'Decryption of crypt12 file was successful.'
msgstore.close()
quit(msg)
def main():
if len(sys.argv) > 2 and len(sys.argv) < 5:
if len(sys.argv) == 3:
outfile = 'msgstore.db'
else:
outfile = sys.argv[3]
if keyfile(sys.argv[1]) and decrypt12(sys.argv[2], outfile):
validate(outfile)
else:
print('\nWhatsApp Crypt12 Database Decrypter '+__version__+' '+__copyright__+' by '+__author__+'\n')
print('\tUsage: python '+str(sys.argv[0])+' key msgstore.db.crypt12 msgstore.db\n')
if __name__ == "__main__":
main()
Code:
Usage: python decrypt12.py key msgstore.db.crypt12 msgstore.db
Java:
Code:
package decrypt12;
/*
*
*** decrypt12.jar: Decrypts WhatsApp msgstore.db.crypt12 files. ***
*
* Author : TripCode
* Copyright : Copyright (C) 2016
* License : GPLv3
* Status : Production
* Version : 1.0
*
*/
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.security.Security;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
// import org.spongycastle.jce.provider.BouncyCastleProvider; // Android
public class decrypt12 {
static {
Security.insertProviderAt(new org.bouncycastle.jce.provider.BouncyCastleProvider(), 1);
// Security.insertProviderAt(new org.spongycastle.jce.provider.BouncyCastleProvider(), 1); // Android
}
public static void decrypt(String KeyFile, String C12File, String SQLFile) throws Exception {
final File tempFile = new File(System.getProperty("java.io.tmpdir") + "/"
+ (int) (System.currentTimeMillis() / 1000L) + "-msgstore.enc");
if (!new File(KeyFile).isFile())
quit("The specified input key file does not exist.");
else if (new File(KeyFile).length() != 158)
quit("The specified input key file is invalid.");
else if (!new File(C12File).isFile())
quit("The specified input crypt12 file does not exist.");
InputStream KeyIn = new FileInputStream(KeyFile);
InputStream WdbIn = new BufferedInputStream(new FileInputStream(C12File));
byte[] KeyData = new byte[158];
KeyIn.read(KeyData);
byte[] T1 = new byte[32];
System.arraycopy(KeyData, 30, T1, 0, 32);
byte[] KEY = new byte[32];
System.arraycopy(KeyData, 126, KEY, 0, 32);
KeyIn.close();
byte[] C12Data = new byte[67];
WdbIn.read(C12Data);
byte[] T2 = new byte[32];
System.arraycopy(C12Data, 3, T2, 0, 32);
byte[] IV = new byte[16];
System.arraycopy(C12Data, 51, IV, 0, 16);
if (!new String(T1, 0, T1.length, "ASCII").equals(new String(T2, 0, T2.length, "ASCII")))
quit("Key file mismatch or crypt12 file is corrupt.");
int InputLength = WdbIn.available();
RandomAccessFile raf = new RandomAccessFile(tempFile, "rw");
byte[] tempBuffer = new byte[1024];
int I;
while ((I = WdbIn.read(tempBuffer)) != -1)
raf.write(tempBuffer, 0, I);
raf.setLength(InputLength - 20);
raf.close();
WdbIn.close();
InputStream PdbSt = new BufferedInputStream(new FileInputStream(tempFile));
Cipher cipher;
Security.addProvider(new BouncyCastleProvider());
cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC"); // BouncyCastle
// cipher = Cipher.getInstance("AES/GCM/NoPadding", "SC"); // SpongyCastle (Android)
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(KEY, "AES"), new IvParameterSpec(IV));
CipherInputStream CipherStream = new CipherInputStream(PdbSt, cipher);
InflaterInputStream CryptOutput = new InflaterInputStream(CipherStream, new Inflater(false));
try {
FileOutputStream InflateBuffer = new FileOutputStream(SQLFile);
int N = 0;
byte[] CryptBuffer = new byte[8192];
while ((N = CryptOutput.read(CryptBuffer)) != -1) {
InflateBuffer.write(CryptBuffer, 0, N);
}
InflateBuffer.close();
} catch (IOException ex) {
quit("Fatal error:" + ex);
}
CipherStream.close();
tempFile.delete();
InputStream SqlDB = new FileInputStream(SQLFile);
byte[] SqlData = new byte[6];
SqlDB.read(SqlData);
byte[] MS = new byte[6];
System.arraycopy(SqlData, 0, MS, 0, 6);
SqlDB.close();
if (!new String(MS, 0, MS.length, "ASCII").toLowerCase().equals("sqlite")) {
new File(SQLFile).delete();
quit("Decryption of crypt12 file has failed.");
}
else
quit("Decryption of crypt12 file was successful.");
}
private static void quit(String Msg) {
System.out.println(Msg);
System.exit(0);
}
public static void main(String[] args) throws Exception {
String outFile;
if (args.length > 1 && args.length < 4) {
if (args.length == 3)
outFile = args[2];
else
outFile = "msgstore.db";
decrypt(args[0], args[1], outFile);
} else {
System.out.println("\nWhatsApp Crypt12 Database Decrypter 1.0 Copyright (C) 2016 by TripCode");
System.out.println("\tUsage: java -jar decrypt12.jar key msgstore.db.crypt12 msgstore.db\n");
}
}
}
Code:
Usage: java -jar decrypt12.jar key msgstore.db.crypt12 msgstore.db
GitHub Repository: WhatsApp-Crypt12-Decrypter
Click to expand...
Click to collapse
error message..line 84..intended error
hi tripcode...i used the python script in python3.6...it showed an intended error..error line 84...can u please help me in this issue..or can u guid me to decrypt the file..am not having that key file..thats y..mobile lost..i retrieved the files from drive..so plz help me in this issue..
error the key file not found
hi it was fine till it shows the key file is not found...plz help me in this issues
GURUMOORTHI said:
hi it was fine till it shows the key file is not found...plz help me in this issues
Click to expand...
Click to collapse
w/o key file ...there is no way to brake the crytp12...
mmmm but i don`t know if there is any chace using brute force to brake the encrytion
Can someone share pycrypto also pycryptodome? or java for Android thanks
gbwhatsapp
Fusseldieb said:
There is a program out there which claims to obtain the key file without root. If it's still working today, I don't know. Here: https://forum.xda-developers.com/showthread.php?t=2770982
If you want the key file, it's better to root your phone and get it. It's not that hard. You can even unroot your phone after catching the key.
And no, someone can't just decrypt the database, because the key is there for a reason, and this reason is security.
Click to expand...
Click to collapse
You can try:
a tutorial from Ik Teach:
https://www.youtube.com/watch?v=4b1f2iTnoO8
link to the file gbwhatsapp:
https://idescargar.com/gbwhatsapp/descargar/
It give you de key file whithout root. It worked for me. But it is a little tricky. and you end up with this modded whatsapp.
Cheers!
hii tripcode
I am not having that key file..
i lost my mobile....i retrieved the files from drive..so plz help me to decrypt my database.
shanya_creation said:
hii tripcode
I am not having that key file..
i lost my mobile....i retrieved the files from drive..so plz help me to decrypt my database.
Click to expand...
Click to collapse
You need to re-download WhatsApp in another phone and use your old number. (Yes, you'll need to recover your phone number before recovering your chats). Once you have WhatsApp installed you can take out the Key file from /data/data/com.whatsapp/files
To do that stuff i recommend to use a old phone that can be easily rooted or one that has already rooted.
Good luck :good:
Hello,
Does anyone know if by any chance KEY file gets deleted on old phone when whatsapp is activated on a new phone and old phone whatsapp gets locked asking for conf code by SMS?
I rooted android 4.x.x
I then searched using ez file manager in root and in data/data /com.whatsapp but i do not see a KEY file.
download WhatsApp Plus8.30 it will work for you
https://goapk.org/whatsapp-plus/
Need Help!
I have whatsapp db.crypt12 file. I am novice in Mobile. Can anybody make that file readable professionally for me? I am ready to pay for this.
HI,
I have extracted the key by the procedure of "WhatsApp Key/DB Extractor 4.7 Enhanced 1.0" (https://forum.xda-developers.com/showthread.php?t=2770982&page=55), but eventually your JAVA code failed with message:
Key file mismatch or crypt12 file is corrupt.
Why is that?
Somewhere (guess at Elcomsoft Explorer) I have read, that the key can only decrypt backups taken from a previous time. This should true in my case, isnt?
1) Is the key somehow related to the phone device itself? (I have used a spare phone for this analysis, so not the original WA was regularly running on.)
Since end of August (when an Upgrade of WA has destroyed my chat history database) I have tried several attempts to restore it by downgrading WA to 2.20.64 and 2.20.89, so the key I have now is not the original of what the crypted backup was created with.
Moreover, due to a database schema error my chat history can only be loaded with WA version previous to 2.20.89 (this is why: https://medium.com/@leonardocezaryc...hatsapp-windows-phone-to-android-6b225918af55)
My experiments now led to the situation, that I not any more can register any pre-2.20.89 version by the SMS verification process, even though I dated my phone back to mid of August.
Thus I currently have no working installation with all my chat history where I could extract a crypto key from.
2) Any ideas how i can bypass Whatsapp to complain about its expired versions and register by SMS again?
3) Is it a hard-coded deadline in the binaries of the app?
4) Does the crypt key change between installations and become incompatible? I wonder, how to restore any old backup then...
Thanks!
samruthstom said:
Hello,
Does anyone know if by any chance KEY file gets deleted on old phone when whatsapp is activated on a new phone and old phone whatsapp gets locked asking for conf code by SMS?
I rooted android 4.x.x
I then searched using ez file manager in root and in data/data /com.whatsapp but i do not see a KEY file.
Click to expand...
Click to collapse
Yes - upon inactivation WA 2.20.89+ destroys the "key" file and instead creates a "backup_token" file.
It is recoverable by activating it via SMS code.
---------- Post added at 07:40 PM ---------- Previous post was at 07:26 PM ----------
heyvijay said:
I have whatsapp db.crypt12 file. I am novice in Mobile. Can anybody make that file readable professionally for me? I am ready to pay for this.
Click to expand...
Click to collapse
What kind of problem can't you solve so far?
There is a commercial solution called "Elcomsoft eXplorer for WhatsApp ".
I also would like and am about to try it out, if you are interested, we can share the costs of it.
After years of successfully using this to access MY chat data, this week it stopped working :-(
WhatsApp on my phone looks to have updated to v2.21.8.17 and is now generating local backups with a .crypt14 extension instead of .crypt12.
Unsurprisingly, this chokes on this with the error Key file mismatch or crypt12 file is corrupt.
However, armed with hexdump and a bit cunning, I've worked out how to tweak the python so that it successfully decodes .crypt14 files.
in a .crypt14 file ... [.py hacks in decrypt12 function shown below in square brackets]
... t2 is at offset 14 [so change to crypt12.seek(14) t2 = crypt12.read(32)]
... iv is at offset 66 [change to crypt12.seek(66) iv = crypt12.read(16)]
... encrypted content starts at offset 99, (I haven't yet worked out the correct amount of footer to remove, but removing 0 seems to result in a successful decryption so far) [change to crypt12.seek(99) primer(tf, crypt12, 0)]
I've also noticed that the 16 bytes at offset 62 to 77 in the key file also appear in the .cryptX file, just like the t bytes at offset 30 to 61 do.
In a .crypt12 file they are at offset 35 to 50.
In a .crypt14 file they are at offset 48 to 63.
In my code I've called these x1 and x2 and do the same equality check as happens for t1 and t2.
In addition, in the .crypt14 file, bytes at 86 to 94 look to contain the WA version number, so in my case 2.21.8.17 - presumably the version that wrote the .crypt14 file. I suspect that when the version number rolls over to more digits (e.g. 2.21.10.10) then the offset to the start of the encrypted content (currently 99 in my backup files) might well change?
adflyer said:
After years of successfully using this to access MY chat data, this week it stopped working :-(
WhatsApp on my phone looks to have updated to v2.21.8.17 and is now generating local backups with a .crypt14 extension instead of .crypt12.
Unsurprisingly, this chokes on this with the error Key file mismatch or crypt12 file is corrupt.
However, armed with hexdump and a bit cunning, I've worked out how to tweak the python so that it successfully decodes .crypt14 files.
in a .crypt14 file ... [.py hacks in decrypt12 function shown below in square brackets]
... t2 is at offset 14 [so change to crypt12.seek(14) t2 = crypt12.read(32)]
... iv is at offset 66 [change to crypt12.seek(66) iv = crypt12.read(16)]
... encrypted content starts at offset 99, (I haven't yet worked out the correct amount of footer to remove, but removing 0 seems to result in a successful decryption so far) [change to crypt12.seek(99) primer(tf, crypt12, 0)]
I've also noticed that the 16 bytes at offset 62 to 77 in the key file also appear in the .cryptX file, just like the t bytes at offset 30 to 61 do.
In a .crypt12 file they are at offset 35 to 50.
In a .crypt14 file they are at offset 48 to 63.
In my code I've called these x1 and x2 and do the same equality check as happens for t1 and t2.
In addition, in the .crypt14 file, bytes at 86 to 94 look to contain the WA version number, so in my case 2.21.8.17 - presumably the version that wrote the .crypt14 file. I suspect that when the version number rolls over to more digits (e.g. 2.21.10.10) then the offset to the start of the encrypted content (currently 99 in my backup files) might well change?
Click to expand...
Click to collapse
It's not working for me for some reason. I don't know what I am missing here. Can you provide the modified code itself?