File "/home/steck/whatsappMy/yowsup/yowsup/layers/protocol_media/layer.py", line 41, in recvMessageStanza
if mediaNode.getAttributeValue("type") == "image":
AttributeError: 'NoneType' object has no attribute 'getAttributeValue'
DATA
Decrypt body:
yowsup/layers/axolotl/layer.py:
def handleWhisperMessage(self, node):
encMessageProtocolEntity = EncryptedMessageProtocolEntity.fromProtocolTreeNode(node)
```
whisperMessage = WhisperMessage(serialized=encMessageProtocolEntity.getEncData())
sessionCipher = self.getSessionCipher(encMessageProtocolEntity.getFrom(False))
plaintext = sessionCipher.decryptMsg(whisperMessage)
if encMessageProtocolEntity.getVersion() == 2:
plaintext = self.unpadV2Plaintext(plaintext)
//PRINT DECRYPT BODY
print plaintext
//
bodyNode = ProtocolTreeNode("body", data = plaintext)
node.addChild(bodyNode)
self.toUpper(node)
```
Link to my file
https://mmi488.whatsapp.net/d/0QVa5QLVNRiH0HZ_gU-W5FbzX-4/AhbVJi2WS1Yia7EklnoFua1fwMezYiqzH4BQsv53_63Z.enc ┴�K\←c��� *�/R���Zc�T㡪Z│ܒM���O·�┘┌��±b�c�H�─�π─U��┌\└ǎ�K91b��←?:◆�;±�⎺��cM&RF���_�M��1���┤4?���d��K'E��̏�
no clue. have you looked at the wa16 branch I think @tgalal has already started working on this. maybe its working there.
also, @mgp25 's the chat-api already implemented this. you can check there.
please post here any progress you have cause currently yowsup is useless
...
File "/usr/local/lib/python2.7/dist-packages/yowsup/layers/init.py", line 59, in toUpper
self.upper.receive(data)
File "/usr/local/lib/python2.7/dist-packages/yowsup/layers/__init.py", line 169, in receive
s.receive(data)
File "/usr/local/lib/python2.7/dist-packages/yowsup/layers/init.py", line 105, in receive
recv(node)
File "/usr/local/lib/python2.7/dist-packages/yowsup/layers/protocol_media/layer.py", line 40, in recvMessageStanza
if mediaNode.getAttributeValue("type") == "image":
AttributeError: 'NoneType' object has no attribute 'getAttributeValue'
File "/usr/local/lib/python2.7/dist-packages/yowsup/layers/protocol_media/protocolentities/message_media_downloadable.py", line 30, in __str__
out = super(DownloadableMediaMessageProtocolEntity, self).__str__()
File "/usr/local/lib/python2.7/dist-packages/yowsup/layers/protocol_media/protocolentities/message_media.py", line 108, in __str__
out += "Media Type: %s\n" % self.mediaType
AttributeError: 'DownloadableMediaMessageProtocolEntity' object has no attribute 'mediaType'
The question is, now we have the encrypted data in value node, we just need to decrypt it. What should be the process to do this? What is the key, where do we get it from, and how do we use it to decrypt the message body? It looks like the image data itself is encoded into the message, which means when we decrypt it we'll have the binary that makes up the image (including exif data etc). So no need to go and download an image from a URL, which makes mediadownloader.py unnecessary..
trying to figure out how to just make this work in the axolotl layer. so far i've changed handleEncMessage to something like this:
def handleEncMessage(self, node):
try:
if node.getChild("enc")["v"] == "2" and node["from"] not in self.v2Jids:
self.v2Jids.append(node["from"])
if node.getChild("enc")["type"] == "pkmsg":
self.handlePreKeyWhisperMessage(node)
elif node.getChild("enc")["type"] == "msg" and node.getChild("enc")["mediatype"] == "image":
self.handleWhisperMessage(node) #what should this be!?
i'm not trying to just ignore the case when a message is received, i'm actually trying to fix the problem. my use case for this requires the ability to receive images. that's why this issue is a bug..
OK, I got to see a preview of the image.
After the function
def handleWhisperMessage (self, node)
We get the binary data. They can parse. We are looking for the title FF D8 (JPEG Header and get a preview of the image! In the same binary data link to the full image, you just get it and decipher!
@jlguardi are you saying without protobuf the contents of the .enc file that gets downloaded can't be fully decrypted? do you have any idea what the file structure is?..
@payamazadi Step by step... I've fully read encrypted message content: url, caption... So I'll decrypt file but I need time/help for that.
Use my branch!
$image->getRefKey() <-- where ???
I use the hex editor to find it. To decrypt at least a test file. But this is the wrong decision to search using hexeditor
4:35 am! time to sleep!
Finally I've some kind of error converting from decrypted but buffered message to an object using protobuf. I get url, mime and caption but seems to fail with sha256. You can try it, it is updated in my fork/encrypted_media.
I hope somebody fixes that before wake up time ;)
changed refkey to use bytes and now it looks like its working.
changed heigh to height and lengt to length, to match with what's being debugged
changed IV to iv in .proto to match with what's being debugged
i am using @jlguardi's encrypted-media branch, so make sure you update to that.
from there, the code is almost exactly the same, here's what you need to do to get where i am:
change layers/axolotl/encrypted_media.proto to this:
File "/home/steck/whatsappMy/yowsup/yowsup/layers/protocol_media/layer.py", line 41, in recvMessageStanza if mediaNode.getAttributeValue("type") == "image": AttributeError: 'NoneType' object has no attribute 'getAttributeValue'
no clue. have you looked at the wa16 branch I think @tgalal has already started working on this. maybe its working there. also, @mgp25 's the chat-api already implemented this. you can check there. please post here any progress you have cause currently yowsup is useless
@Dimelay can you please post the code to simple ignore image messages for now, so it won't break the code? (until someone will solve the problem)
@yniv Edit file yowsup/layers/protocol_media/layer.py
Find and modify function def recvMessageStanza(self, node): pass
There is little time for this. Simple ignore
Sorry/ google translate =)
@Dimelay but maybe we need to send ack anyway?
@yniv Done! Receive notification about the image and sent 'ack' package It does not fall. How can you put the files? =)
yowsup/layers/protocol_media/layer.py
def recvMessageStanza(self, node): if node.getAttributeValue("type") == "media": mediaNode = node.getChild("enc") if mediaNode.getAttributeValue("mediatype") == "image": entity = ImageDownloadableMediaMessageProtocolEntity.fromProtocolTreeNode(node) self.toUpper(entity) print 'protocol_media/layer.py recv image from %s' % node.getAttributeValue("from") elif mediaNode.getAttributeValue("type") == "audio": entity = AudioDownloadableMediaMessageProtocolEntity.fromProtocolTreeNode(node) self.toUpper(entity) elif mediaNode.getAttributeValue("type") == "video": entity = VideoDownloadableMediaMessageProtocolEntity.fromProtocolTreeNode(node) self.toUpper(entity) elif mediaNode.getAttributeValue("type") == "location": entity = LocationMediaMessageProtocolEntity.fromProtocolTreeNode(node) self.toUpper(entity) elif mediaNode.getAttributeValue("type") == "vcard": entity = VCardMediaMessageProtocolEntity.fromProtocolTreeNode(node) self.toUpper(entity)
yowsup/layers/protocol_media/protocolentities/message_media_downloadable.py
@staticmethod def fromProtocolTreeNode(node): entity = MediaMessageProtocolEntity.fromProtocolTreeNode(node) entity.class = DownloadableMediaMessageProtocolEntity """ mediaNode = node.getChild("media") entity.setDownloadableMediaProps( mediaNode.getAttributeValue("mimetype"), mediaNode.getAttributeValue("filehash"), mediaNode.getAttributeValue("url"), mediaNode.getAttributeValue("ip"), mediaNode.getAttributeValue("size"), mediaNode.getAttributeValue("file") ) """ return entity
yowsup/layers/protocol_media/protocolentities/message_media_downloadable_image.py
@staticmethod def fromProtocolTreeNode(node): entity = DownloadableMediaMessageProtocolEntity.fromProtocolTreeNode(node) entity.class = ImageDownloadableMediaMessageProtocolEntity """ mediaNode = node.getChild("media") entity.setImageProps( mediaNode.getAttributeValue("encoding"), mediaNode.getAttributeValue("width"), mediaNode.getAttributeValue("height"), mediaNode.getAttributeValue("caption"), ) """ return entity
yowsup/layers/protocol_media/protocolentities/message_media.py
@staticmethod def fromProtocolTreeNode(node): entity = MessageProtocolEntity.fromProtocolTreeNode(node) entity.class = MediaMessageProtocolEntity """ entity.setMediaType(node.getChild("media").getAttributeValue("type")) preview = node.getChild("media").getData() entity.setPreview(preview) """ return entity
I have this problem, is it the same?
... File "/usr/local/lib/python2.7/dist-packages/yowsup/layers/init.py", line 59, in toUpper self.upper.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup/layers/__init.py", line 169, in receive s.receive(data) File "/usr/local/lib/python2.7/dist-packages/yowsup/layers/init.py", line 105, in receive recv(node) File "/usr/local/lib/python2.7/dist-packages/yowsup/layers/protocol_media/layer.py", line 40, in recvMessageStanza if mediaNode.getAttributeValue("type") == "image": AttributeError: 'NoneType' object has no attribute 'getAttributeValue'
yes
https://github.com/tgalal/yowsup/issues/1389 you can try solution which i propose here to ignore these scenarios in meanwhile
@Dimelay could you pls post your code with indentation? use three of this character: ` (<- copy paste ;) before and after the code.
Thanks! A
I'm trying to do it
okay fixed
not resolve for me:
@bdbais @jlguardi the above is a step in the right direction - following changes:
This makes things conform to the new encrypted XML body, which @Dimelay alluded to, which is something like:
The question is, now we have the encrypted data in value
node
, we just need to decrypt it. What should be the process to do this? What is the key, where do we get it from, and how do we use it to decrypt the message body? It looks like the image data itself is encoded into the message, which means when we decrypt it we'll have the binary that makes up the image (including exif data etc). So no need to go and download an image from a URL, which makes mediadownloader.py unnecessary..This is the full printout from below, with some relevant areas bolded
trying to figure out how to just make this work in the axolotl layer. so far i've changed handleEncMessage to something like this:
@bdbais not resolve for me:
You use yowsup-cli.py or written by you script ? For yowsup-cli.py edit /yowsup/demos/cli/layer.py @ProtocolEntityCallback("message") Line 513
Now, if I get the picture, my script does not crash and gives the message
i'm not trying to just ignore the case when a message is received, i'm actually trying to fix the problem. my use case for this requires the ability to receive images. that's why this issue is a bug..
I'm using a script based on echoclient for receiving media from users, but now I can't use it. Error is already present.
yes, you are right, that is what we are trying to fix. don't know how to properly decrypt the media message
OK, I got to see a preview of the image. After the function
def handleWhisperMessage (self, node)
We get the binary data. They can parse. We are looking for the title FF D8 (JPEG Header and get a preview of the image! In the same binary data link to the full image, you just get it and decipher!@Dimelay that sounds like it'd work - can you post the code here?
ok, i see what yuo're saying. i'm doing something like this:
@payamazadi @Dimelay I've gotten preview of the image and I've partially ported chatAPI in my branch (https://github.com/jlguardi/yowsup/tree/encrypted_media)
As you can see, it produces still an exception but preview node is correct. I have printed to a file and works.
Now, I'm trying to use protobuf to read all other fields (url is possible without protobuf but we need all other fields to decrypt remote file).
@jlguardi are you saying without protobuf the contents of the .enc file that gets downloaded can't be fully decrypted? do you have any idea what the file structure is?..
@payamazadi Step by step... I've fully read encrypted message content: url, caption... So I'll decrypt file but I need time/help for that. Use my branch!
@jlguardi let me know what i can do to help. if you can point me to where in chat-api i need to look to port, i can help w that
$keys = (new HKDFv3())->deriveSecrets($image->getRefKey(), hex2bin('576861747341707020496d616765204b657973'), 112); $keys = substr($keys, 16); $parts = str_split($keys, 32); $key = $parts[0]; //KEY!
pkcs5_unpad(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $cipherImage, MCRYPT_MODE_CBC, $iv));
I'm in file chatAPI "handlers/MessageHandler.php +443" I have up to here.
But last half hour I was working with utf-8/latin-1? exception with captions.
$image->getRefKey() <-- where ??? I use the hex editor to find it. To decrypt at least a test file. But this is the wrong decision to search using hexeditor
const REFKEY = 8;
pb_wa_messages.php
or did you mean where to put it in the port..
I've 'almost' implemented gerRefKey. So I need to continue decrypting but now I'm getting an error while reading with protobuff.
I've pushed my last code.
@payamazadi This is the position in the buffer
4:35 am! time to sleep! Finally I've some kind of error converting from decrypted but buffered message to an object using protobuf. I get url, mime and caption but seems to fail with sha256. You can try it, it is updated in my fork/encrypted_media. I hope somebody fixes that before wake up time ;)
why is the .proto file for sha256 using string? shouldn't it be bytes? https://developers.google.com/protocol-buffers/docs/proto#scalar
i switched it to bytes, installed protobuff, and compiled, and now the error is past sha256 and onto refkey.
changed refkey to use bytes and now it looks like its working. changed heigh to height and lengt to length, to match with what's being debugged changed IV to iv in .proto to match with what's being debugged
now i get something like this with your existing debug statements: URL: https://mmi447.whatsapp.net/d/cVtP9_0aOCLhA_-zJOYru1b0wes/Ap6sE4raJ1oJp1t1Lq8GVhgcZr2HRaTToA7PHaB-_UOU.enc MIME: image/jpeg CAPTION: SHA: �Yǧ�g���M�聹ty�p�H�VU��ߨ� LENGTH: 123313 HEIGHT: 1600 WIDTH: 900 REFKEY: ��(�������ķ��W��$�[�3LJ�� KEY: THUMB: ----node--
Show you code REFKEY its good/
type=7 and cpp_type=7 ?
i'm not sure yet, i'm about to start decrypting
i am using @jlguardi's encrypted-media branch, so make sure you update to that. from there, the code is almost exactly the same, here's what you need to do to get where i am:
if it makes it easier, here's the updated encrypted_media_pb2.py file (but still make sure to update the .proto file as above):
issued pull request on @jlguardi 's encrypted-media branch https://github.com/jlguardi/yowsup/pull/2
I did it!
you did!? share the code!!!
Image save in /tmp/MY
axolotl/layer.py from Crypto.Cipher import AES import urllib2 from axolotl.kdf.hkdfv3 import HKDFv3 from axolotl.util.byteutil import ByteUtil
Now we have to generate Protocol TreeNode is simply