Introduction
The objective of this project is to create an GPL client to Lively.com (Dead project)
As the protocol is not available, the work is based on different techniques like reverse engineering, sniffers and common sense.
Protocol
After running a protocol analyzer (wireshark), I found that the Lively client uses XMPP (Jabber) protocol for authentication and messaging.
After checking the files on Google/Lively/Flex is obviuos that some of the code was made using Adobe Flex technology. The good new is that Sothink SWF Decompiler is able to dissamble the SWF file like Login.swf, so I expect to be able to analyze how to login to the server.
Using API Monitor I was able to determine that the library used to encrypt the XMPP messages is secur32.dll, so I’ve made a dll proxy to be able to read the data before to get encrypted and when it comes back, after been decrypted.
Also using HxD I was able to read the memory of the application that seems to be made with Visual C++ for 3D (DirectX) and Adobe Flash for windows and forms, I could check the strings before be encrypted and send to the server. The messages are in some kind of XML encrypted inside a XMPP message.
Login.SWF Decompiled
After decompiling and analyzing the code of \Google\Lively\flex\Login.SWF I’ve found:
file: \LoginController.as:
public function doLogin() : void
{
username = login.username.text;
if (useStoredPassword)
{
}// end if
Antenna.instance.sendCommand("_l", login.remember.selected,
!passwordChanged, login.username.text, login.password.text);
return;
}// end function
file: \Action\com\google\g3dweb\common\Antenna.as:
public function sendCommand(... args) : Object
{
if (!debugMode)
{
return ExternalInterface.call.apply(null, args);
}// end if
log("ANTENNA: sendCommand(" + args.join(", ") + ")");
return {};
}// end function
So in this way the Visual C++ client interact with the SWF files.
Secur32.dll Proxy
To been able to read the data that is send and received, I’ve done a dll proxy. More information about how to do it, can be found here:
http://www.codeproject.com/KB/DLL/CreateYourProxyDLLs.aspx
The source code of the dll proxy is here: secur32.zip and the compiled library is here: secur32.dll
To use it, you need to create a directory in c:\logs and copy the proxy secur32.dll to the Lively directory.
After doing that, rename it to secur31.dll and copy the original secur32.dll (system32) to the Lively directory.
Rename the original secur32.dll in the Lively directory to secur32_.dll
After that, you need to edit the client.exe and replace the string: “secur32.dll” to “secur31.dll” (using an hex editor).
Now you’re done. So execute the client.exe and watch the log files in c:\logs\
Here you can see an example of how looks the dump:
= Init = [EncryptMessage] 0 START cBuffers: 4 [EncryptMessage] 0 buffer[1] size: 130 [EncryptMessage] 0 buffer[1] data: <stream:stream to="gmail.com" xml:lang="en" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client"> [EncryptMessage] 0 END [DecryptMessage] 0 START cBuffers: 4 [DecryptMessage] 0 buffer[1] size: 176 [DecryptMessage] 0 buffer[1] data: <?xml version="1.0" encoding="UTF-8"?>< ;stream:stream from="gmail.com" id="2352CC46DE11B711" version="1.0"xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client"> [DecryptMessage] 0 END [DecryptMessage] 0 START cBuffers: 4 [DecryptMessage] 0 buffer[1] size: 166 [DecryptMessage] 0 buffer[1] data: <stream:features><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>PLAIN</mechanism> <mechanism>X-GOOGLE-TOKEN</mechanism></mechanisms> </stream:features> [DecryptMessage] 0 END [EncryptMessage] 0 START cBuffers: 4 [EncryptMessage] 0 buffer[1] size: 385 [EncryptMessage] 0 buffer[1] data: <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="X-GOOGLE-TOKEN">XXXXXXXXXXXXXXXXXXXXXXX</auth> [EncryptMessage] 0 END [DecryptMessage] 0 START cBuffers: 4 [DecryptMessage] 0 buffer[1] size: 51 [DecryptMessage] 0 buffer[1] data: <success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/> [DecryptMessage] 0 END [EncryptMessage] 0 START cBuffers: 4 [EncryptMessage] 0 buffer[1] size: 130 [EncryptMessage] 0 buffer[1] data: <stream:stream to="gmail.com" xml:lang="en" version="1.0" xmlns:stream=" http://etherx.jabber.org/streams" xmlns="jabber:client"> [EncryptMessage] 0 END [DecryptMessage] 0 START cBuffers: 4 [DecryptMessage] 0 buffer[1] size: 176 [DecryptMessage] 0 buffer[1] data: <?xml version="1.0" encoding="UTF-8"?><stream:stream from="gmail.com" id="92A4B029617BC47C" version=" 1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client"> [DecryptMessage] 0 END [DecryptMessage] 0 START cBuffers: 4 [DecryptMessage] 0 buffer[1] size: 137 [DecryptMessage] 0 buffer[1] data: <stream:features><bind xmlns=" urn:ietf:params:xml:ns:xmpp-bind"/><session xmlns=quot urn:ietf:params:xml:ns:xmpp-session"/></stream:features> [DecryptMessage] 0 END [EncryptMessage] 0 START cBuffers: 4 [EncryptMessage] 0 buffer[1] size: 115 [EncryptMessage] 0 buffer[1] data: <iq type="set" id="0"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><resource> libjingleplus</resource></bind></iq> [EncryptMessage] 0 END [DecryptMessage] 0 START cBuffers: 4 [DecryptMessage] 0 buffer[1] size: 135 [DecryptMessage] 0 buffer[1] data: <iq id="0" type="result"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><jid> spamfelipe2@gmail.com/libjinglep59B75216</jid></bind></iq> [DecryptMessage] 0 END
* I’ve replaced my Google Token for security reason. The token is a base64 string that contains my email (username) and a big string (I think that is the token).
The full log dump can be found here: sniff_secur32_A12207.txt
HxD Dump of Lively Client
The complete file is here: Lively Memory Dump. I don’t know if the strings are correct, maybe they can be a little corrupt.
I have indented the file so is easier to read it, an extract of the file look like this:
Whose room is this?
<message to="spamfelipe2@gmail.com/libjinglep8F9CEED3" type="groupchat" id="73" from="lively 108@3dconf.google.com/-5578858927619228622_2541031"> <body>Whose room is this?</body> </message> <presence to="spamfelipe2@gmail.com/libjinglep568823DE" id="369" from="lively-108@3dconf.google.com/2912906431397233772_24952671"> <show>away</show> <status/> <priority>0</priority> <x stamp="20080711T23:40:39" xmlns="jabber:x:delay"/> <nick:nick xmlns:nick="http://jabber.org/protocol/nick"> lucas3088 </nick:nick> <plugin xmlns="google:plugin"> <capability> 3dweb </capability> <data> CxXj3mXEHWy7qEMlwmSCwgwtAZGsPTABSt0BCJelqfr54P+XBBolCMH+w9 WF09OpNBCVn8HzwfON8H8Yl6Wp+vng/5cEINC9k/jkEBonCIC8j6fDzLPXjwEQ vZ/26/KaiZmgARiXpan6+eD/lwQg0L2T+OQQGioImv+w89Sd6 K/lARDb3fWBzJif2rcBGJelqfr54P+XBCDsiIib9Z6utigaKQitwOyX8r+5p+cBENn0p4 jNi4XxbhiXpan6+eD/lwQg7IiIm/WerrYoGioIy92Nyqf5hcXBARD/s++qqLbP2LsBGJel qfr54P+XBCDsiIib9Z6utig= </data> </plugin> <x xmlns="vcard-temp:x:update"> <photo/> </x> <user:x xmlns:user="http://jabber.org/protocol/muc#user"> <user:item affiliation="none" role="participant"/> </user:x> </presence> <message type="groupchat" from="lively-108@3dconf.google.com/2912906431397233772_24952671" to="spamfelipe2@gmail.com/libjinglep568823DE"> <plugin xmlns="google:plugin"> <capability> 3dweb </capability> <data> CAmLApAC7IiIm/WerrYomAIBjAI= </data> </plugin> </message>
File Format
After comparing the data on the memory of Lively and the data retrieved using the dll proxy, they match. So the format is basically using XMPP protocol with some extension.
The binary data is send inside tags and following the XMPP standard, they are coded in Base64.
I think that the data containing the coordinates of the user is sended in a binary format, in the tag. As this method is not efficient, the big files are downloaded using an external url. The data is compressed with gzip and samples can be found in the Temporary Internet Files. Those files are compressed with gzip:
gp[8]: gzip compressed data, max compression
It also appear that some of the 3D files are in Gamebryo format:
less gp_8.dump
And the file contains this string: Gamebryo File Format, Version 20.2.0.8
Others interesting strings:
NIF Creation Information >> P:/Google/3DWeb/Project/Assets/01_normals_logan/Export/NIF & Texture Sources/geo/01_normals_logan_export-07.09.27-v01.mb >> Platform = Generic >> Gamebryo Version:2.2.2.0 Exporter Plugin Version:7.3 >> NiMultiShader Version:7.0 >> Maya Unlimited 7.0 eyebrows.NIF eyebrows_NiMultiShader headShape:1 skin.NIF skin_NiMultiShader eyer eyerShape right_eye.NIF right_eye_NiMultiShader NIF Creation Information >> P:/Google/3DWeb/Project/Assets/01_normals_logan/Export/NIF & Texture Sources/geo/01_normals_logan_export-07.10.17-v02.mb >> Platform = Generic >> Gamebryo Version:2.2.2.0 Exporter Plugin Version:7.3 >> NiMultiShader Version:7.0 >> Maya Unlimited 7.0
So to me this seems to be a container file, with a great mix of file formats. Here are two files if you want to look at: 1.zip 2.zip
I got the files from (as the windows cache says):
- http://clients3.google.com/lively/s/gp?id=6330964325628602226&obj_ed=0
- http://clients3.google.com/lively/s/gp?id=7778763701070530893&obj_ed=0
* You need to be logged in and send an special header with an AUTH cookie to be able to get the files
The problem is that Gamebryo doesn’t have a demonstration/trial kit and the format seems to be proprietary. There is a project to open Gamebryo files (NifTools) but it doesn’t work for me. Anyone want to decode it ?
0 Comments until now
Add your Comment!