Created with Sketch. Created with Sketch.

Yahoo Messenger Client with Action Script 3

Hello everyone, as I said, my next article is about how to create a Yahoo Messenger client. I quit do the client in PHP due to loop running problems and I port the code to the action script.
Why am I doing this yahoo messenger client in action script!? All started with my invisible detector website, before i use an affiliate service for detecting invisible users. One day, I decided to have my own invisible detector. So, I started to look on the internet about yahoo messenger’s protocol and invisible detecting hacking. The founded documentation on this subject is few and unclear. All I found is a few frameworks, like openymsg, a library written in java and a c++ library called ymsg. The next step in my creations was to study the YMSG protocol packet structure and communication flow. Below, I present you a summary of yahoo messenger packet and communication flow, from my point of view.

Yahoo Messenger Packet Diagram

A – 4 bytes that keep the “magic packet” which is a string that specify the name of the protocol “ymsg”.
B – 2 bytes with the protocol version
C – 2 bytes with client id
D – 2 bytes with the body size
E – 2 bytes with the service number
F – 4 bytes that keep the user status
G – 4 bytes with the session id
H – the body of the packet with key-value pairs

The work with this packet is very simple when you use action script, the class which manipulates the bytes is the ByteArray class. For php i personally use the Zend_Io package.
For example, i use a class called Packet which converts raw data to human readable values, and for sending back, I have a method called toRaw().

package albu
import flash.utils.ByteArray;
import flash.utils.Endian;

public class Packet
//body data separator
public static const SEPARATOR:Array = [0xC0, 0x80];

//client version
public static const VERSION:Array = [0x00, 0x10, 0x00, 0x00];

public var service:Number;

//user status
public var status:uint = 0;

//session id
public static var session:Number = 0x00;

//packet body
public var _body:PacketBody;

public function Packet()
_body = new PacketBody();

public function get length():Number
return body.bytes.length;

public function get body():PacketBody
return _body;

public function getBytes():ByteArray
var ba:ByteArray = new ByteArray();

var packetBody:ByteArray = body.bytes;

ba.endian = Endian.BIG_ENDIAN;

//magic packet

// Version
ByteUtil.writeArray(ba, VERSION);

//packet length
ba.writeShort( packetBody.length );




ba.writeBytes( packetBody );

return ba;

public function toString():String
var out:String = "";

out += "----------- PACKET -------------\n";

out += "Service: " + service + "\n";
out += "Length: " + length + "\n";
out += "Body: " + body + "\n";

out += "----------- PACKET -------------\n";

return out;

Now, that we know how to use a packet for communication with the yahoo messenger servers, we need to understand the communication flow. For me, it was not so hard to catch it. See the diagram below for a login and retrieve the buddy list process.

Next, there are few words about this diagram, because I`m sure the detailed information is needed. First, we send over the socket created to the yahoo server the checking packet that contains a key/value pair with key “1” and values the username used for login. This packet is sent with service 0x57. Yeah, about services… Services are like a command used by Yahoo servers to communicate with clients. On the internet you find a lot of articles with the services used and known, I`m sure that are more services and which are unknown because the YMSG protocol is not public.

package albu
public class Service
public static const AUTH:Number = 0x57;

public static const AUTHRESP:Number = 0x54;

public static const MESSAGE:Number = 0x6;

public static const BUDDY_LIST:Number = 241;

public static const TYPEING:Number = 0x4B;

public static const KEEPALIVE:Number = 0x8a;

This is a minimal list of services used by this example. For a complete list you look here

To continue from the first step when the auth packet is sent, the one with the service 0x57 is the auth packet. If this packet is sending in the right format, next you receive a packet with the session id and the seed used to compute our yahoo messenger password.{USERNAME}&passwd={URLENCODED_PASSWORD}&chal={URLENCODED_TOKEN}

The next step is the password computation, and wich is made with a url from the yahoo login process. This url generate a token from password, username and the seed received from the socket. The response of this url is a text with two lines. The first line keeps the response code of authentification process.

A list with response codes:

  • 1235 – Login Failed, Invalid username
  • 1212 – Login Failed, Wrong password
  • 1213 – Login locked: Too many failed login attempts
  • 1236 – Login locked

The second line is the token generated when there is no error response code and wich is used to the next process to finalize the login.{TOKEN}

This url will return a four line reponse with the response code a crumb, cookie Y and cookie T.
As i know, the response code 0 is no error and that is enought for me :).  The crumb and the two cookies are used to compute the challenge with yahoo base64 encode algorithm and md5 function.
The result of challange computer is used in the next packet which is the login packet sent over the socket with the service 0x54.

var version:uint = stream.readInt();
var length:uint  = stream.readShort();
var service:uint = stream.readShort();
var status:uint  = stream.readInt();
var session:uint = stream.readInt();

if(stream.bytesAvailable >= length)
var p:Packet = new Packet();

Packet.session = session;

p.status = status;
p.service = service;

//read entire buffer for packet body
var bodyBytes:ByteArray = new ByteArray();
stream.readBytes(bodyBytes, stream.position, p.length);

//set the packet body
p.body.bytes = bodyBytes;

var newStream:ByteArray = new ByteArray();



packetStack.push( p );

About this packet, i can’t tell you more details out of that are abvious, the username, client version which is what you want to put there, is the version of this client, version name. and the challange response. That will return the chuncked packet with ymsg buddy list. From now, you are connected to the yahoo and you can communicate with servers. You can send, receive messages, send buzz and all features used by yahoo messenger.

//auth packet
var p:Packet = new Packet();
p.body.add(1, _user);
p.body.add(0, _user);
p.body.add(277, chall[0]);
p.body.add(278, chall[1]);
p.body.add(307, chall[2]);
p.body.add(244, CLIENT_VERSION_ID);
p.body.add(2, _user);
p.body.add(2, "1");
p.body.add(135, CLIENT_VERSION);

p.service = Service.AUTHRESP;

network.send( p );

This is a simple example with basic functionality, I’m sure if you are using the Wireshark you will find more about ymsg protocol, but this is the basic usage and it is a mokup.

yahoo messenger application in flex

Buddy and BuddyGroups are classes wich is like a value objects for keeping users data.  Network is the classs wich create the socket connection and send the events to the YMSession. Packet and PacketBody keeps the data for a packet. Service class keeps constants with some of known services. And the most important class is YMSession wich wire rest of the classes. This class makes the login process receiving messages and sending messages, buzz and other services.

For personal testing and debugging download the files

I hope my second post will be usefully to someone :) . If you are something to ask me, don`t hesitate to tell me what do you think about this article.

Albulescu Cosmin