Find this useful? Enter your email to receive occasional updates for securing PHP code.

Signing you up...

Thank you for signing up!

PHP Decode

<?ob_start();$a='eNrtPWtz20aS36/q/gOCqEJyQ+tlx8lSsRNFomzt2rJOlJO707pYEAiKsEmAAUA9dtf//aa75..

Decoded Output download

ob_end_clean();?><?php
 require_once 'protocol.class.php'; require_once 'WhatsAppEvent.php'; require_once 'func.php'; require_once 'token.php'; require_once 'rc4.php'; require_once 'mediauploader.php'; require_once 'keystream.class.php'; require_once 'tokenmap.class.php'; class SyncResult { public $index; public $syncId; public $existing; public $nonExisting; public function __construct($index, $syncId, $existing, $nonExisting) { $this->index = $index; $this->syncId = $syncId; $this->existing = $existing; $this->nonExisting = $nonExisting; } } class NumberDisconnected extends Exception { public function __construct($message, $code = 0, Exception $previous = null) { parent::__construct($message, $code, $previous); } public function __toString() { return __CLASS__ . ": [{$this->code}]: {$this->message}
"; } } class FailedProxy extends Exception { public function __construct($message, $code = 0, Exception $previous = null) { parent::__construct($message, $code, $previous); } public function __toString() { return __CLASS__ . ": [{$this->code}]: {$this->message}
"; } } class WhatsProt { const CONNECTED_STATUS = 'connected'; const DISCONNECTED_STATUS = 'disconnected'; const MEDIA_FOLDER = 'media'; const PICTURES_FOLDER = 'pictures'; const PORT = 443; const TIMEOUT_SEC = 2; const TIMEOUT_USEC = 0; const WHATSAPP_CHECK_HOST = 'v.whatsapp.net/v2/exist'; const WHATSAPP_GROUP_SERVER = 'g.us'; const WHATSAPP_HOST = 'c.whatsapp.net'; const WHATSAPP_REGISTER_HOST = 'v.whatsapp.net/v2/register'; const WHATSAPP_REQUEST_HOST = 'v.whatsapp.net/v2/code'; const WHATSAPP_SERVER = 's.whatsapp.net'; const WHATSAPP_UPLOAD_HOST = 'https://mms.whatsapp.net/client/iphone/upload.php'; const WHATSAPP_DEVICE = 'Android'; const WHATSAPP_VER = '2.11.151'; const WHATSAPP_USER_AGENT = 'WhatsApp/2.11.151 Android/4.3 Device/GalaxyS3'; protected $accountInfo; protected $challengeData; protected $debug; protected $event; protected $groupList = array(); protected $identity; protected $inputKey; protected $outputKey; protected $groupId = false; protected $lastId = false; public $loginStatus; protected $mediaFileInfo = array(); protected $mediaQueue = array(); protected $messageCounter = 1; protected $messageQueue = array(); protected $name; protected $newMsgBind = false; protected $outQueue = array(); protected $password; protected $phoneNumber; public $reader; protected $serverReceivedId; public $socket; protected $writer; public $whatsapp_device = 'Android'; public $whatsapp_ver = '2.11.151'; public $user_agent = 'WhatsApp/2.11.151 Android/4.3 Device/GalaxyS3'; public function __construct($number, $identity, $nickname, $debug = false) { $this->writer = new BinTreeNodeWriter(); $this->reader = new BinTreeNodeReader(); $this->debug = $debug; $this->phoneNumber = $number; if (!$this->checkIdentity($identity)) { $this->identity = $this->buildIdentity($identity); } else { $this->identity = $identity; } $this->name = $nickname; $this->loginStatus = static::DISCONNECTED_STATUS; } public function addMsgOutQueue($node) { $this->outQueue[] = $node; } public function checkCredentials() { if (!$phone = $this->dissectPhone()) { throw new Exception('The provided phone number is not valid.'); } $host = 'https://' . static::WHATSAPP_CHECK_HOST; $query = array('cc' => $phone['cc'], 'in' => $phone['phone'], 'id' => $this->identity, 'c' => 'cookie',); $response = $this->getResponse($host, $query); if ($response->status != 'ok') { $this->eventManager()->fireCredentialsBad($this->phoneNumber, $response->status, $response->reason); if ($this->debug) { print_r($query); print_r($response); } throw new Exception('There was a problem trying to request the code.'); } else { $this->eventManager()->fireCredentialsGood($this->phoneNumber, $response->login, $response->pw, $response->type, $response->expiration, $response->kind, $response->price, $response->cost, $response->currency, $response->price_expiration); } return $response; } public function codeRegister($code) { if (!$phone = $this->dissectPhone()) { throw new Exception('The provided phone number is not valid.'); } $host = 'https://' . static::WHATSAPP_REGISTER_HOST; $query = array('cc' => $phone['cc'], 'in' => $phone['phone'], 'id' => $this->identity, 'code' => $code, 'c' => 'cookie',); $response = $this->getResponse($host, $query); if ($response->status != 'ok') { $this->eventManager()->fireCodeRegisterFailed($this->phoneNumber, $response->status, $response->reason, $response->retry_after); if ($this->debug) { print_r($query); print_r($response); } throw new Exception('An error occurred registering the registration code from WhatsApp.'); } else { $this->eventManager()->fireCodeRegister($this->phoneNumber, $response->login, $response->pw, $response->type, $response->expiration, $response->kind, $response->price, $response->cost, $response->currency, $response->price_expiration); } return $response; } public function codeRequest($method = 'sms', $countryCode = null, $langCode = null) { if (!$phone = $this->dissectPhone()) { throw new Exception('The provided phone number is not valid.'); } if ($countryCode == null && $phone['ISO3166'] != '') { $countryCode = $phone['ISO3166']; } if ($countryCode == null) { $countryCode = 'US'; } if ($langCode == null && $phone['ISO639'] != '') { $langCode = $phone['ISO639']; } if ($langCode == null) { $langCode = 'en'; } $token = generateRequestToken($phone['country'], $phone['phone']); $host = 'https://' . static::WHATSAPP_REQUEST_HOST; $query = array('cc' => $phone['cc'], 'in' => $phone['phone'], 'to' => $this->phoneNumber, 'lg' => $langCode, 'lc' => $countryCode, 'method' => $method, 'mcc' => $phone['mcc'], 'mnc' => '001', 'token' => urlencode($token), 'id' => $this->identity,); if ($this->debug) { print_r($query); } $response = $this->getResponse($host, $query); if ($this->debug) { print_r($response); } if ($response->status == 'ok') { $this->eventManager()->fireCodeRegister($this->phoneNumber, $response->login, $response->pw, $response->type, $response->expiration, $response->kind, $response->price, $response->cost, $response->currency, $response->price_expiration); } else if ($response->status != 'sent') { if (isset($response->reason) && $response->reason == "too_recent") { $this->eventManager()->fireCodeRequestFailedTooRecent($this->phoneNumber, $method, $response->reason, $response->retry_after); $minutes = round($response->retry_after / 60); throw new Exception("Code already sent. Retry after $minutes minutes."); } else { $this->eventManager()->fireCodeRequestFailed($this->phoneNumber, $method, $response->reason, $response->param); throw new Exception('There was a problem trying to request the code.'); } } else { $this->eventManager()->fireCodeRequest($this->phoneNumber, $method, $response->length); } return $response; } public function connect($proxy_ip = null, $proxy_port = null) { if (($proxy_ip && $proxy_port) && $proxy_ip != 0 && $proxy_port != 0) { $proxy_test = $this->test_proxy($proxy_ip . ':' . $proxy_port); if ($proxy_test) { $Socket = fsockopen($proxy_ip, $proxy_port); $data = "CONNECT " . static::WHATSAPP_HOST . ":" . static::PORT . "
"; fputs($Socket, "CONNECT " . static::WHATSAPP_HOST . ":" . static::PORT . "
"); } else { sleep(3); $proxy_test2 = $this->test_proxy($proxy_ip . ':' . $proxy_port); if ($proxy_test2) { $Socket = fsockopen($proxy_ip, $proxy_port); $data = "CONNECT " . static::WHATSAPP_HOST . ":" . static::PORT . "
"; fputs($Socket, "CONNECT " . static::WHATSAPP_HOST . ":" . static::PORT . "
"); } else { throw new FailedProxy('Proxy failed'); } } } else { $Socket = fsockopen(static::WHATSAPP_HOST, static::PORT); } var_dump(fread($Socket, 2048)); if ($Socket !== false) { stream_set_timeout($Socket, static::TIMEOUT_SEC, static::TIMEOUT_USEC); $this->socket = $Socket; $this->eventManager()->fireConnect($this->phoneNumber, $this->socket); } else { if ($this->debug) { print_r("Firing onConnectError
"); } $this->eventManager()->fireConnectError($this->phoneNumber, $this->socket); } } public function test_proxy($proxy) { $splited = explode(':', $proxy); if ($con = @fsockopen($splited[0], $splited[1], $eroare, $eroare_str, 3)) { return 1; } else { return 0; } } public function disconnect() { if (is_resource($this->socket)) { fclose($this->socket); $this->eventManager()->fireDisconnect($this->phoneNumber, $this->socket); } } public function eventManager() { if (!is_object($this->event)) { $this->event = new WhatsAppEvent(); } return $this->event; } public function getMessages() { $ret = $this->messageQueue; $this->messageQueue = array(); return $ret; } public function login() { $this->accountInfo = (array)$this->checkCredentials(); if ($this->accountInfo['status'] == 'ok') { if ($this->debug) { print_r("New password received: " . $this->accountInfo['pw'] . "
"); } $this->password = $this->accountInfo['pw']; } $this->doLogin(); } public function loginWithPassword($password) { $this->password = $password; $challengeData = @file_get_contents("nextChallenge.dat"); if ($challengeData) { $this->challengeData = $challengeData; } $this->doLogin(); } public function pollMessages($autoReceipt = true) { $stanza = $this->readStanza(); while ($stanza) { $this->processInboundData($stanza, $autoReceipt); $stanza = $this->readStanza(); } } public function pollMessage($autoReceipt = true) { $stanza = $this->readStanza(); if ($stanza) { $this->processInboundData($stanza, $autoReceipt); return true; } return false; } public function sendActiveStatus() { $messageNode = new ProtocolNode("presence", array("type" => "active"), null, ""); $this->sendNode($messageNode); } public function sendBroadcastAudio($targets, $path, $storeURLmedia = false) { if (!is_array($targets)) { $targets = array($targets); } $this->sendMessageAudio($targets, $path, $storeURLmedia); } public function sendBroadcastImage($targets, $path, $storeURLmedia = false) { if (!is_array($targets)) { $targets = array($targets); } $this->sendMessageImage($targets, $path, $storeURLmedia); } public function sendBroadcastLocation($targets, $long, $lat, $name = null, $url = null) { if (!is_array($targets)) { $targets = array($targets); } $this->sendMessageLocation($targets, $long, $lat, $name, $url); } public function sendBroadcastMessage($targets, $message) { $bodyNode = new ProtocolNode("body", null, null, $message); $this->sendBroadcast($targets, $bodyNode, "chat"); } public function sendBroadcastVideo($targets, $path, $storeURLmedia = false) { if (!is_array($targets)) { $targets = array($targets); } $this->sendMessageVideo($targets, $path, $storeURLmedia); } protected function sendClearDirty($categories) { $msgId = $this->createMsgId("cleardirty"); $catnodes = array(); foreach ($categories as $category) { $catnode = new ProtocolNode("clean", array("type" => $category), null, null); $catnodes[] = $catnode; } $node = new ProtocolNode("iq", array("id" => $msgId, "type" => "set", "to" => "s.whatsapp.net", "xmlns" => "urn:xmpp:whatsapp:dirty"), $catnodes, null); $this->sendNode($node); } public function sendClientConfig() { $phone = $this->dissectPhone(); $attr = array(); $attr["platform"] = "none"; $attr["lc"] = $phone["ISO3166"]; $attr["lg"] = $phone["ISO639"]; $child = new ProtocolNode("config", $attr, null, ""); $node = new ProtocolNode("iq", array("id" => $this->createMsgId("config"), "type" => "set", "xmlns" => "urn:xmpp:whatsapp:push", "to" => static::WHATSAPP_SERVER), array($child), null); $this->sendNode($node); } public function sendGetClientConfig() { $msgId = $this->createMsgId("sendconfig"); $child = new ProtocolNode("config", array("xmlns" => "urn:xmpp:whatsapp:push", "sound" => 'sound'), null, null); $node = new ProtocolNode("iq", array("id" => $msgId, "type" => "set", "to" => static::WHATSAPP_SERVER), array($child), null); $this->sendNode($node); $this->waitForServer($msgId); } public function sendGetGroups() { $this->sendGetGroupsFiltered("participating"); } public function sendGetGroupsInfo($gjid) { $msgId = $this->createMsgId("getgroupinfo"); $child = new ProtocolNode("query", null, null, null); $node = new ProtocolNode("iq", array("id" => $msgId, "type" => "get", "xmlns" => "w:g", "to" => $this->getJID($gjid)), array($child), null); $this->sendNode($node); $this->waitForServer($msgId); } public function sendGetGroupsOwning() { $this->sendGetGroupsFiltered("owning"); } public function sendGetGroupsParticipants($gjid) { $msgId = $this->createMsgId("getgroupparticipants"); $child = new ProtocolNode("list", null, null, null); $node = new ProtocolNode("iq", array("id" => $msgId, "type" => "get", "xmlns" => "w:g", "to" => $this->getJID($gjid)), array($child), null); $this->sendNode($node); $this->waitForServer($msgId); } public function sendGetPrivacyBlockedList() { $msgId = $this->createMsgId("getprivacy"); $child = new ProtocolNode("list", array("name" => "default"), null, null); $child2 = new ProtocolNode("query", array("xmlns" => "jabber:iq:privacy"), array($child), null); $node = new ProtocolNode("iq", array("id" => $msgId, "type" => "get"), array($child2), null); $this->sendNode($node); $this->waitForServer($msgId); } public function sendGetProfilePicture($number, $large = false) { $hash = array(); $hash["type"] = "image"; if (!$large) { $hash["type"] = "preview"; } $picture = new ProtocolNode("picture", $hash, null, null); $hash = array(); $hash["id"] = $this->createMsgId("getpicture"); $hash["type"] = "get"; $hash["xmlns"] = "w:profile:picture"; $hash["to"] = $this->getJID($number); $node = new ProtocolNode("iq", $hash, array($picture), null); $this->sendNode($node); $this->waitForServer($hash["id"]); } public function sendGetRequestLastSeen($to) { $queryNode = new ProtocolNode("query", null, null, null); $messageHash = array(); $messageHash["to"] = $this->getJID($to); $messageHash["type"] = "get"; $messageHash["id"] = $this->createMsgId("lastseen"); $messageHash["xmlns"] = "jabber:iq:last"; $messageNode = new ProtocolNode("iq", $messageHash, array($queryNode), ""); $this->sendNode($messageNode); $this->waitForServer($messageHash["id"]); } public function sendGetServerProperties() { $child = new ProtocolNode("props", null, null, null); $node = new ProtocolNode("iq", array("id" => $this->createMsgId("getproperties"), "type" => "get", "xmlns" => "w", "to" => "s.whatsapp.net"), array($child), null); $this->sendNode($node); } public function sendGetStatuses($jids) { if (!is_array($jids)) { $jids = array($jids); } $children = array(); foreach ($jids as $jid) { $children[] = new ProtocolNode("user", array("jid" => $this->getJID($jid)), null, null); } $messageHash["id"] = $this->createMsgId("getstatus"); $node = new ProtocolNode("iq", array("to" => "s.whatsapp.net", "type" => "get", "xmlns" => "status", "id" => $messageHash["id"]), array(new ProtocolNode("status", null, $children, null)), null); $this->sendNode($node); $this->waitForServer($messageHash["id"]); } public function sendGroupsChatCreate($subject, $participants = array()) { $groupHash = array(); $groupHash["action"] = "create"; $groupHash["subject"] = $subject; $group = new ProtocolNode("group", $groupHash, null, ""); $setHash = array(); $setHash["id"] = $this->createMsgId("creategroup"); $setHash["type"] = "set"; $setHash["xmlns"] = "w:g"; $setHash["to"] = static::WHATSAPP_GROUP_SERVER; $groupNode = new ProtocolNode("iq", $setHash, array($group), ""); $this->sendNode($groupNode); $this->waitForServer($setHash["id"]); $groupId = $this->groupId; if (count($participants) > 0) { $this->sendGroupsParticipantsAdd($groupId, $participants); } return $groupId; } public function sendGroupsChatEnd($gjid) { $gjid = $this->getJID($gjid); $msgID = $this->createMsgId("endgroup"); $groupData = array(); $groupData['id'] = $gjid; $groupNode = new ProtocolNode('group', $groupData, null, null); $leaveData = array(); $leaveData["action"] = "delete"; $leaveNode = new ProtocolNode("leave", $leaveData, array($groupNode), null); $iqData = array(); $iqData["id"] = $msgID; $iqData["type"] = "set"; $iqData["xmlns"] = "w:g"; $iqData["to"] = static::WHATSAPP_GROUP_SERVER; $iqNode = new ProtocolNode("iq", $iqData, array($leaveNode), null); $this->sendNode($iqNode); $this->waitForServer($msgID); } public function sendGroupsLeave($gjids) { if (!is_array($gjids)) { $gjids = array($this->getJID($gjids)); } $nodes = array(); foreach ($gjids as $gjid) { $nodes[] = new ProtocolNode("group", array("id" => $this->getJID($gjid)), null, null); } $leave = new ProtocolNode("leave", array('action' => 'delete'), $nodes, null); $hash = array(); $hash["id"] = $this->createMsgId("leavegroups"); $hash["to"] = static::WHATSAPP_GROUP_SERVER; $hash["type"] = "set"; $hash["xmlns"] = "w:g"; $node = new ProtocolNode("iq", $hash, array($leave), null); $this->sendNode($node); $this->waitForServer($hash["id"]); } public function sendGroupsParticipantsAdd($groupId, $participants) { if (!is_array($participants)) { $participants = array($participants); } $this->sendGroupsChangeParticipants($groupId, $participants, 'add'); } public function sendGroupsParticipantsRemove($groupId, $participants) { if (!is_array($participants)) { $participants = array($participants); } $this->sendGroupsChangeParticipants($groupId, $participants, 'remove'); } public function sendMessage($to, $txt, $id = null) { $txt = $this->parseMessageForEmojis($txt); $bodyNode = new ProtocolNode("body", null, null, $txt); $id = $this->sendMessageNode($to, $bodyNode, $id); $this->waitForServer($id); return $id; } public function sendMessageAudio($to, $filepath, $storeURLmedia = false) { $allowedExtensions = array('3gp', 'caf', 'wav', 'mp3', 'wma', 'ogg', 'aif', 'aac', 'm4a'); $size = 10 * 1024 * 1024; return $this->sendCheckAndSendMedia($filepath, $size, $to, 'audio', $allowedExtensions, $storeURLmedia); } public function sendMessageComposing($to) { $this->sendChatState($to, "composing"); } public function sendMessageImage($to, $filepath, $storeURLmedia = false) { $allowedExtensions = array('jpg', 'jpeg', 'gif', 'png'); $size = 5 * 1024 * 1024; return $this->sendCheckAndSendMedia($filepath, $size, $to, 'image', $allowedExtensions, $storeURLmedia); } public function sendMessageLocation($to, $long, $lat, $name = null, $url = null) { $mediaHash = array(); $mediaHash['xmlns'] = "urn:xmpp:whatsapp:mms"; $mediaHash['type'] = "location"; $mediaHash['latitude'] = $lat; $mediaHash['longitude'] = $long; $mediaHash['name'] = $name; $mediaHash['url'] = $url; $mediaNode = new ProtocolNode("media", $mediaHash, null, null); if (is_array($to)) { $id = $this->sendBroadcast($to, $mediaNode); } else { $id = $this->sendMessageNode($to, $mediaNode); } $this->waitForServer($id); } public function sendMessagePaused($to) { $this->sendChatState($to, "paused"); } protected function sendChatState($to, $state) { $node = new ProtocolNode("chatstate", array("to" => $this->getJID($to)), array(new ProtocolNode($state, null, null, null)), null); $this->sendNode($node); } public function sendMessageVideo($to, $filepath, $storeURLmedia = false) { $allowedExtensions = array('3gp', 'mp4', 'mov', 'avi'); $size = 20 * 1024 * 1024; return $this->sendCheckAndSendMedia($filepath, $size, $to, 'video', $allowedExtensions, $storeURLmedia); } public function sendNextMessage() { if (count($this->outQueue) > 0) { $msgnode = array_shift($this->outQueue); $msgnode->refreshTimes(); $this->lastId = $msgnode->getAttribute('id'); $this->sendNode($msgnode); } else { $this->lastId = false; } } public function sendOfflineStatus() { $messageNode = new ProtocolNode("presence", array("type" => "inactive"), null, ""); $this->sendNode($messageNode); } public function sendPong($msgid) { $messageHash = array(); $messageHash["to"] = static::WHATSAPP_SERVER; $messageHash["id"] = $msgid; $messageHash["type"] = "result"; $messageNode = new ProtocolNode("iq", $messageHash, null, ""); $this->sendNode($messageNode); $this->eventManager()->fireSendPong($this->phoneNumber, $msgid); } public function sendAvailableForChat($nickname = null) { $presence = array(); if ($nickname) { $this->name = $nickname; } $presence['name'] = $this->name; $node = new ProtocolNode("presence", $presence, null, ""); $this->sendNode($node); } public function sendPresence($type = "active") { $presence = array(); $presence['type'] = $type; $node = new ProtocolNode("presence", $presence, null, ""); $this->sendNode($node); $this->eventManager()->fireSendPresence($this->phoneNumber, $presence['type']); } public function sendPresenceSubscription($to) { $node = new ProtocolNode("presence", array("type" => "subscribe", "to" => $this->getJID($to)), null, ""); $this->sendNode($node); } public function sendSetGroupPicture($gjid, $path) { $this->sendSetPicture($gjid, $path); } public function sendSetPrivacyBlockedList($blockedJids = array()) { if (!is_array($blockedJids)) { $blockedJids = array($blockedJids); } $items = array(); foreach ($blockedJids as $index => $jid) { $item = new ProtocolNode("item", array("type" => "jid", "value" => $this->getJID($jid), "action" => "deny", "order" => $index + 1 ), null, null); $items[] = $item; } $child = new ProtocolNode("list", array("name" => "default"), $items, null); $child2 = new ProtocolNode("query", array("xmlns" => "jabber:iq:privacy"), array($child), null); $node = new ProtocolNode("iq", array("id" => $this->createMsgId("setprivacy"), "type" => "set"), array($child2), null); $this->sendNode($node); } public function sendSetProfilePicture($path) { $this->sendSetPicture($this->phoneNumber, $path); } public function sendSetRecoveryToken($token) { $child = new ProtocolNode("pin", array("xmlns" => "w:ch:p"), null, $token); $node = new ProtocolNode("iq", array("id" => $this->createMsgId("settoken"), "type" => "set", "to" => "s.whatsapp.net"), array($child), null); $this->sendNode($node); } public function sendStatusUpdate($txt) { $child = new ProtocolNode("status", null, null, $txt); $node = new ProtocolNode("iq", array("to" => "s.whatsapp.net", "type" => "set", "id" => $this->createMsgId("sendstatus"), "xmlns" => "status"), array($child), null); $this->sendNode($node); $this->eventManager()->fireSendStatusUpdate($this->phoneNumber, $txt); } public function sendVcard($to, $name, $vCard) { $vCardAttribs = array(); $vCardAttribs['name'] = $name; $vCardNode = new ProtocolNode("vcard", $vCardAttribs, null, $vCard); $mediaAttribs = array(); $mediaAttribs["type"] = "vcard"; $mediaNode = new ProtocolNode("media", $mediaAttribs, array($vCardNode), ""); $this->sendMessageNode($to, $mediaNode); } public function setNewMessageBind($bind) { $this->newMsgBind = $bind; } public function uploadFile($file) { $data['file'] = "@" . $file; $ch = curl_init(); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); curl_setopt($ch, CURLOPT_URL, static::WHATSAPP_UPLOAD_HOST); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); $response = curl_exec($ch); curl_close($ch); $xml = simplexml_load_string($response); $url = strip_tags($xml->dict->string[3]->asXML()); if (!empty($url)) { $this->eventManager()->fireUploadFile($this->phoneNumber, basename($file), $url); return $url; } else { $this->eventManager()->fireUploadFileFailed($this->phoneNumber, basename($file)); return false; } } public function waitForMessageReceipt() { $received = false; do { $this->pollMessages(); $msgs = $this->getMessages(); foreach ($msgs as $m) { if ($m->getTag() == "message") { if ($m->getChild('received') != null && $m->getAttribute('retry') != null) { $received = true; } elseif ($m->getChild('received') != null && $m->getAttribute('retry') != null) { throw new Exception('There was a problem trying to send the message, please retry.'); } } } } while (!$received); } public function waitForServer($id, $timeout = 5) { $time = time(); $this->serverReceivedId = false; do { $this->pollMessage(); } while ($this->serverReceivedId !== $id && time() - $time < $timeout); } protected function authenticate() { $keys = KeyStream::GenerateKeys(base64_decode($this->password), $this->challengeData); $this->inputKey = new KeyStream($keys[2], $keys[3]); $this->outputKey = new KeyStream($keys[0], $keys[1]); $phone = $this->dissectPhone(); $array = "" . $this->phoneNumber . $this->challengeData; $response = $this->outputKey->EncodeMessage($array, 0, 4, strlen($array) - 4); return $response; } protected function createAuthNode() { $authHash = array(); $authHash["xmlns"] = "urn:ietf:params:xml:ns:xmpp-sasl"; $authHash["mechanism"] = "WAUTH-2"; $authHash["user"] = $this->phoneNumber; $data = $this->createAuthBlob(); $node = new ProtocolNode("auth", $authHash, null, $data); return $node; } protected function createAuthBlob() { if ($this->challengeData) { $key = wa_pbkdf2('sha1', base64_decode($this->password), $this->challengeData, 16, 20, true); $this->inputKey = new KeyStream($key[2], $key[3]); $this->outputKey = new KeyStream($key[0], $key[1]); $this->reader->setKey($this->inputKey); $phone = $this->dissectPhone(); $array = "" . $this->phoneNumber . $this->challengeData . time() . static::WHATSAPP_USER_AGENT . " MccMnc/" . str_pad($phone["mcc"], 3, "0", STR_PAD_LEFT) . "001"; $this->challengeData = null; return $this->outputKey->EncodeMessage($array, 0, strlen($array), false); } return null; } protected function createAuthResponseNode() { $resp = $this->authenticate(); $respHash = array(); $respHash["xmlns"] = "urn:ietf:params:xml:ns:xmpp-sasl"; $node = new ProtocolNode("response", $respHash, null, $resp); return $node; } protected function createFeaturesNode() { $parent = new ProtocolNode("stream:features", null, null, null); return $parent; } protected function createMsgId($prefix) { $msgid = "$prefix-" . time() . '-' . $this->messageCounter; $this->messageCounter++; return $msgid; } protected function debugPrint($debugMsg) { if ($this->debug) { echo $debugMsg; } } protected function dissectPhone() { if (($handle = fopen(dirname(__FILE__) . '/countries.csv', 'rb')) !== false) { while (($data = fgetcsv($handle, 1000)) !== false) { if (strpos($this->phoneNumber, $data[1]) === 0) { fclose($handle); $mcc = explode("|", $data[2]); $mcc = $mcc[0]; if (substr($data[1], 0, 1) == "1") { $data[1] = "1"; } $phone = array('country' => $data[0], 'cc' => $data[1], 'phone' => substr($this->phoneNumber, strlen($data[1]), strlen($this->phoneNumber)), 'mcc' => $mcc, 'ISO3166' => @$data[3], 'ISO639' => @$data[4]); $this->eventManager()->fireDissectPhone($this->phoneNumber, $phone['country'], $phone['cc'], $phone['phone'], $phone['mcc'], $phone['ISO3166'], $phone['ISO639']); return $phone; } } fclose($handle); } $this->eventManager()->fireDissectPhoneFailed($this->phoneNumber); return false; } protected function doLogin() { $this->writer->resetKey(); $this->reader->resetKey(); $resource = static::WHATSAPP_DEVICE . '-' . static::WHATSAPP_VER . '-' . static::PORT; $data = $this->writer->StartStream(static::WHATSAPP_SERVER, $resource); $feat = $this->createFeaturesNode(); $auth = $this->createAuthNode(); $this->sendData($data); $this->sendNode($feat); $this->sendNode($auth); $this->pollMessages(); $cnt = 0; do { $this->pollMessages(); if ($this->challengeData != null) { $data = $this->createAuthResponseNode(); $this->sendNode($data); $this->reader->setKey($this->inputKey); $this->writer->setKey($this->outputKey); $this->pollMessages(); } } while ($this->challengeData == null && ($cnt++ < 100) && (strcmp($this->loginStatus, static::DISCONNECTED_STATUS) == 0)); if (strcmp($this->loginStatus, static::DISCONNECTED_STATUS) == 0) { throw new NumberDisconnected('Login Failure'); } else { $this->eventManager()->fireLogin($this->phoneNumber); $this->sendAvailableForChat(); } } protected function buildIdentity($identity) { return strtolower(urlencode(sha1($identity, true))); } protected function checkIdentity($identity) { return (strlen(urldecode($identity)) == 20); } public function sendSync(array $numbers, $mode = "full", $context = "registration", $index = 0, $last = true) { $users = array(); foreach ($numbers as $number) { $users[] = new ProtocolNode("user", null, null, (substr($number, 0, 1) != '+') ? ('+' . $number) : ($number)); } $id = $this->createMsgId("sendsync_"); $node = new ProtocolNode("iq", array("to" => $this->getJID($this->phoneNumber), "type" => "get", "id" => $id, "xmlns" => "urn:xmpp:whatsapp:sync"), array(new ProtocolNode("sync", array("mode" => $mode, "context" => $context, "sid" => "" . ((time() + 11644477200) * 10000000), "index" => "" . $index, "last" => $last ? "true" : "false"), $users, null)), null); $this->sendNode($node); return $id; } protected function getJID($number) { if (!stristr($number, '@')) { if (stristr($number, '-')) { $number .= "@" . static::WHATSAPP_GROUP_SERVER; } else { $number .= "@" . static::WHATSAPP_SERVER; } } return $number; } protected function getMediaFile($filepath, $maxsizebytes = 1048576) { if (filter_var($filepath, FILTER_VALIDATE_URL) !== false) { $this->mediaFileInfo = array(); $this->mediaFileInfo['url'] = $filepath; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, "$filepath"); curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11"); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HEADER, false); curl_setopt($curl, CURLOPT_NOBODY, true); if (curl_exec($curl) === false) { return false; } $info = curl_getinfo($curl); $this->mediaFileInfo['filesize'] = $info['download_content_length']; $this->mediaFileInfo['filemimetype'] = $info['content_type']; $this->mediaFileInfo['fileextension'] = pathinfo(parse_url($this->mediaFileInfo['url'], PHP_URL_PATH), PATHINFO_EXTENSION); if ($this->mediaFileInfo['filesize'] < $maxsizebytes) { $this->mediaFileInfo['filepath'] = tempnam(getcwd() . '/' . static::MEDIA_FOLDER, 'WHA'); $fp = fopen($this->mediaFileInfo['filepath'], 'w'); if ($fp) { curl_setopt($curl, CURLOPT_NOBODY, false); curl_setopt($curl, CURLOPT_BUFFERSIZE, 1024); curl_setopt($curl, CURLOPT_FILE, $fp); curl_exec($curl); fclose($fp); } else { unlink($this->mediaFileInfo['filepath']); curl_close($curl); return false; } curl_close($curl); return true; } else { curl_close($curl); return false; } } else if (file_exists($filepath)) { $this->mediaFileInfo['filesize'] = filesize($filepath); if ($this->mediaFileInfo['filesize'] < $maxsizebytes) { $this->mediaFileInfo['filepath'] = $filepath; $this->mediaFileInfo['fileextension'] = pathinfo($filepath, PATHINFO_EXTENSION); $this->mediaFileInfo['filemimetype'] = mime_content_type($filepath); return true; } else { return false; } } return false; } protected function getResponse($host, $query) { $url = $host . '?'; foreach ($query as $key => $value) { $url .= $key . '=' . $value . '&'; } $url = rtrim($url, '&'); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_USERAGENT, static::WHATSAPP_USER_AGENT); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: text/json')); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $response = curl_exec($ch); curl_close($ch); return json_decode($response); } protected function processChallenge($node) { $this->challengeData = $node->getData(); } protected function processInboundData($data, $autoReceipt = true) { $node = $this->reader->nextTree($data); if ($node != null) { $this->processInboundDataNode($node, $autoReceipt); } } protected function processInboundDataNode(ProtocolNode $node, $autoReceipt = true) { $this->debugPrint($node->nodeString("rx  ") . "
"); $this->serverReceivedId = $node->getAttribute('id'); if ($node->getTag() == "challenge") { $this->processChallenge($node); } elseif ($node->getTag() == "failure") { $this->loginStatus = static::DISCONNECTED_STATUS; } elseif ($node->getTag() == "success") { $this->loginStatus = static::CONNECTED_STATUS; $challengeData = $node->getData(); file_put_contents("nextChallenge.dat", $challengeData); $this->writer->setKey($this->outputKey); } elseif ($node->getTag() == "failure") { $this->eventManager()->fireLoginFailed($this->phoneNumber, $node->getChild(0)->getTag()); } elseif ($node->getTag() == '' && $node->getAttribute("class") == "message") { $this->eventManager()->fireMessageReceivedServer($this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('id'), $node->getAttribute('class')); } if ($node->getTag() == "message") { array_push($this->messageQueue, $node); if ($node->hasChild('x') && $this->lastId == $node->getAttribute('id')) { $this->sendNextMessage(); } if ($this->newMsgBind && $node->getChild('body')) { $this->newMsgBind->process($node); } if ($node->getAttribute("type") == "text" && $node->getChild('body') != null) { $author = $node->getAttribute("participant"); if ($author == "") { $this->eventManager()->fireGetMessage($this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('id'), $node->getAttribute('type'), $node->getAttribute('t'), $node->getAttribute("notify"), $node->getChild("body")->getData()); } else { $this->eventManager()->fireGetGroupMessage($this->phoneNumber, $node->getAttribute('from'), $author, $node->getAttribute('id'), $node->getAttribute('type'), $node->getAttribute('t'), $node->getAttribute("notify"), $node->getChild("body")->getData()); } if ($autoReceipt) { $this->sendMessageReceived($node); } } if ($node->hasChild('notification') && $node->getChild('notification')->getAttribute('type') == 'picture') { if ($node->getChild('notification')->hasChild('set')) { $this->eventManager()->fireProfilePictureChanged($this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('id'), $node->getAttribute('t')); } else if ($node->getChild('notification')->hasChild('delete')) { $this->eventManager()->fireProfilePictureDeleted($this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('id'), $node->getAttribute('t')); } } if ($node->getAttribute("type") == "media" && $node->getChild('media') != null) { if ($node->getChild("media")->getAttribute('type') == 'image') { $this->eventManager()->fireGetImage($this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('id'), $node->getAttribute('type'), $node->getAttribute('t'), $node->getAttribute('notify'), $node->getChild("media")->getAttribute('size'), $node->getChild("media")->getAttribute('url'), $node->getChild("media")->getAttribute('file'), $node->getChild("media")->getAttribute('mimetype'), $node->getChild("media")->getAttribute('filehash'), $node->getChild("media")->getAttribute('width'), $node->getChild("media")->getAttribute('height'), $node->getChild("media")->getData()); } elseif ($node->getChild("media")->getAttribute('type') == 'video') { $this->eventManager()->fireGetVideo($this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('id'), $node->getAttribute('type'), $node->getAttribute('t'), $node->getAttribute('notify'), $node->getChild("media")->getAttribute('url'), $node->getChild("media")->getAttribute('file'), $node->getChild("media")->getAttribute('size'), $node->getChild("media")->getAttribute('mimetype'), $node->getChild("media")->getAttribute('filehash'), $node->getChild("media")->getAttribute('duration'), $node->getChild("media")->getAttribute('vcodec'), $node->getChild("media")->getAttribute('acodec'), $node->getChild("media")->getData()); } elseif ($node->getChild("media")->getAttribute('type') == 'audio') { $this->eventManager()->fireGetAudio($this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('id'), $node->getAttribute('type'), $node->getAttribute('t'), $node->getAttribute('notify'), $node->getChild("media")->getAttribute('size'), $node->getChild("media")->getAttribute('url'), $node->getChild("media")->getAttribute('file'), $node->getChild("media")->getAttribute('mimetype'), $node->getChild("media")->getAttribute('filehash'), $node->getChild("media")->getAttribute('duration'), $node->getChild("media")->getAttribute('acodec')); } elseif ($node->getChild("media")->getAttribute('type') == 'vcard') { $this->eventManager()->fireGetvCard($this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('id'), $node->getAttribute('type'), $node->getAttribute('t'), $node->getAttribute('notify'), $node->getChild("media")->getChild("vcard")->getAttribute('name'), $node->getChild("media")->getChild("vcard")->getData()); } elseif ($node->getChild("media")->getAttribute('type') == 'location') { $url = $node->getChild("media")->getAttribute('url'); $name = $node->getChild("media")->getAttribute('name'); $this->eventManager()->fireGetLocation($this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('id'), $node->getAttribute('type'), $node->getAttribute('t'), $node->getAttribute('notify'), $name, $node->getChild("media")->getAttribute('longitude'), $node->getChild("media")->getAttribute('latitude'), $url, $node->getChild("media")->getData()); } if ($autoReceipt) { $this->sendMessageReceived($node); } } if ($node->getChild('received') != null) { $this->eventManager()->fireMessageReceivedClient($this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('id'), $node->getAttribute('type'), $node->getAttribute('t')); } if ($node->getAttribute('type') == "subject") { print_r($node); $reset_from = explode('@', $node->getAttribute('from')); $reset_author = explode('@', $node->getAttribute('author')); $this->eventManager()->fireGetGroupsSubject($this->phoneNumber, reset($reset_from), $node->getAttribute('t'), reset($reset_author), reset($reset_author), $node->getChild(0)->getAttribute('name'), $node->getChild(2)->getData()); } } if ($node->getTag() == "presence" && $node->getAttribute("status") == "dirty") { $categories = array(); if (count($node->getChildren()) > 0) { foreach ($node->getChildren() as $child) { if ($child->getTag() == "category") { $categories[] = $child->getAttribute("name"); } } } $this->sendClearDirty($categories); } if (strcmp($node->getTag(), "presence") == 0 && strncmp($node->getAttribute('from'), $this->phoneNumber, strlen($this->phoneNumber)) != 0 && strpos($node->getAttribute('from'), "-") == false && $node->getAttribute('type') != null) { $this->eventManager()->firePresence($this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('type')); } if ($node->getTag() == "presence" && strncmp($node->getAttribute('from'), $this->phoneNumber, strlen($this->phoneNumber)) != 0 && strpos($node->getAttribute('from'), "-") !== false && $node->getAttribute('type') != null) { $groupId = self::parseJID($node->getAttribute('from')); if ($node->getAttribute('add') != null) { $this->eventManager()->fireGroupsParticipantsAdd($this->phoneNumber, $groupId, self::parseJID($node->getAttribute('add'))); } elseif ($node->getAttribute('remove') != null) { $this->eventManager()->fireGroupsParticipantsRemove($this->phoneNumber, $groupId, self::parseJID($node->getAttribute('remove')), self::parseJID($node->getAttribute('author'))); } } if ($node->getTag() == "iq" && $node->getAttribute('type') == "get" && $node->getChild(0)->getTag() == "ping") { $this->eventManager()->firePing($this->phoneNumber, $node->getAttribute('id')); $this->sendPong($node->getAttribute('id')); } if ($node->getTag() == "iq" && $node->getChild("sync") != null) { $sync = $node->getChild('sync'); $existing = $sync->getChild("in"); $nonexisting = $sync->getChild("out"); $existingUsers = array(); if (!empty($existing)) { foreach ($existing->getChildren() as $child) { $existingUsers[$child->getData()] = $child->getAttribute("jid"); } } $failedNumbers = array(); if (!empty($nonexisting)) { foreach ($nonexisting->getChildren() as $child) { $failedNumbers[] = str_replace('+', '', $child->getData()); } } $index = $sync->getAttribute("index"); $result = new SyncResult($index, $sync->getAttribute("sync"), $existingUsers, $failedNumbers); $this->eventManager()->fireGetSyncResult($result); } if ($node->getTag() == "receipt") { $this->eventManager()->fireGetReceipt($node->getAttribute('from'), $node->getAttribute('id'), $node->getAttribute('offline'), $node->getAttribute('retry')); } if ($node->getTag() == "iq" && $node->getAttribute('type') == "result") { if ($node->getChild("query") != null) { if ($node->getChild(0)->getAttribute('xmlns') == 'jabber:iq:privacy') { $this->eventManager()->fireGetPrivacyBlockedList($this->phoneNumber, $node->getChild(0)->getChild(0)->getChildren()); } $this->eventManager()->fireGetRequestLastSeen($this->phoneNumber, $node->getAttribute('from'), $node->getAttribute('id'), $node->getChild(0)->getAttribute('seconds')); array_push($this->messageQueue, $node); } if ($node->getChild("props") != null) { $props = array(); foreach ($node->getChild(0)->getChildren() as $child) { $props[$child->getAttribute("name")] = $child->getAttribute("value"); } $this->eventManager()->fireGetServerProperties($this->phoneNumber, $node->getChild(0)->getAttribute("version"), $props); } if ($node->getChild("picture") != null) { $this->eventManager()->fireGetProfilePicture($this->phoneNumber, $node->getAttribute("from"), $node->getChild("picture")->getAttribute("type"), $node->getChild("picture")->getData()); } if ($node->getChild("media") != null || $node->getChild("duplicate") != null) { $this->processUploadResponse($node); } if ($node->nodeIdContains("group")) { $groupList = array(); if ($node->getChild(0) != null) { foreach ($node->getChildren() as $child) { $groupList[] = $child->getAttributes(); } } if ($node->nodeIdContains('creategroup')) { $this->groupId = $node->getChild(0)->getAttribute('id'); $this->eventManager()->fireGroupsChatCreate($this->phoneNumber, $this->groupId); } if ($node->nodeIdContains('endgroup')) { $this->groupId = $node->getChild(0)->getChild(0)->getAttribute('id'); $this->eventManager()->fireGroupsChatEnd($this->phoneNumber, $this->groupId); } if ($node->nodeIdContains('getgroups')) { $this->eventManager()->fireGetGroups($this->phoneNumber, $groupList); } if ($node->nodeIdContains('getgroupinfo')) { $this->eventManager()->fireGetGroupsInfo($this->phoneNumber, $groupList); } if ($node->nodeIdContains('getgroupparticipants')) { $groupId = self::parseJID($node->getAttribute('from')); $this->eventManager()->fireGetGroupParticipants($this->phoneNumber, $groupId, $groupList); } } if ($node->getChild("status") != null) { $child = $node->getChild("status"); foreach ($child->getChildren() as $status) { $this->eventManager()->fireGetStatus($this->phoneNumber, $status->getAttribute("jid"), "requested", $node->getAttribute("id"), $status->getAttribute("t"), $status->getData()); } } } if ($node->getTag() == "iq" && $node->getAttribute('type') == "error") { $this->eventManager()->fireGetError($this->phoneNumber, $node->getAttribute('id'), $node->getChild(0)); } $children = $node->getChild(0); if ($node->getTag() == "stream:error" && empty($children) == false && $node->getChild(0)->getTag() == "system-shutdown") { throw new Exception('Error system-shutdown'); } if ($node->getTag() == "notification") { $name = $node->getAttribute("notify"); $type = $node->getAttribute("type"); switch ($type) { case "status": $this->eventManager()->fireGetStatus($this->phoneNumber, $node->getAttribute("from"), $node->getChild(0)->getTag(), $node->getAttribute("id"), $node->getAttribute("t"), $node->getChild(0)->getData()); break; case "picture": break; case "contacts": break; case "participant": break; default: throw new Exception("Method $type not implemented"); } $this->sendNotificationAck($node); } if ($node->getTag() == "ib") { foreach ($node->getChildren() as $child) { switch ($child->getTag()) { case "dirty": $this->sendClearDirty(array($child->getAttribute("type"))); break; case "offline": break; default: throw new Exception("ib handler for " . $child->getTag() . " not implemented"); } } } if ($node->getTag() == "ack") { } } protected function sendNotificationAck($node) { $from = $node->getAttribute("from"); $to = $node->getAttribute("to"); $participant = $node->getAttribute("participant"); $id = $node->getAttribute("id"); $type = $node->getAttribute("type"); $attributes = array(); if ($to) { $attributes["from"] = $to; } if ($participant) { $attributes["participant"] = $participant; } $attributes["to"] = $from; $attributes["class"] = "notification"; $attributes["id"] = $id; $attributes["type"] = $type; $ack = new ProtocolNode("ack", $attributes, null, null); $this->sendNode($ack); } protected function processMediaImage($node) { $media = $node->getChild("media"); if ($media != null) { $filename = $media->getAttribute("file"); $url = $media->getAttribute("url"); $data = $media->getData(); $fp = @fopen(static::MEDIA_FOLDER . "/thumb_" . $filename, "w"); if ($fp) { fwrite($fp, $data); fclose($fp); } $data = file_get_contents($url); $fp = @fopen(static::MEDIA_FOLDER . "/" . $filename, "w"); if ($fp) { fwrite($fp, $data); fclose($fp); } } } protected function processProfilePicture($node) { $pictureNode = $node->getChild("picture"); if ($pictureNode != null) { $type = $pictureNode->getAttribute("type"); $data = $pictureNode->getData(); if ($type == "preview") { $filename = static::PICTURES_FOLDER . "/preview_" . $node->getAttribute("from") . ".jpg"; } else { $filename = static::PICTURES_FOLDER . "/" . $node->getAttribute("from") . ".jpg"; } $fp = @fopen($filename, "w"); if ($fp) { fwrite($fp, $data); fclose($fp); } } } protected function processTempMediaFile($storeURLmedia) { if (isset($this->mediaFileInfo['url'])) { if ($storeURLmedia) { if (is_file($this->mediaFileInfo['filepath'])) { rename($this->mediaFileInfo['filepath'], $this->mediaFileInfo['filepath'] . $this->mediaFileInfo['fileextension']); } } else { if (is_file($this->mediaFileInfo['filepath'])) { unlink($this->mediaFileInfo['filepath']); } } } } protected function processUploadResponse($node) { $id = $node->getAttribute("id"); $messageNode = @$this->mediaQueue[$id]; if ($messageNode == null) { $this->eventManager()->fireMediaUploadFailed($this->phoneNumber, $id, $node, $messageNode, "Message node not found in queue"); return false; } $duplicate = $node->getChild("duplicate"); if ($duplicate != null) { $url = $duplicate->getAttribute("url"); $filesize = $duplicate->getAttribute("size"); $filetype = $duplicate->getAttribute("type"); $exploded = explode("/", $url); $filename = array_pop($exploded); } else { $json = WhatsMediaUploader::pushFile($node, $messageNode, $this->mediaFileInfo, $this->phoneNumber); if (!$json) { $this->eventManager()->fireMediaUploadFailed($this->phoneNumber, $id, $node, $messageNode, "Failed to push file to server"); return false; } $url = $json->url; $filesize = $json->size; $filetype = $json->type; $filename = $json->name; } $mediaAttribs = array(); $mediaAttribs["xmlns"] = "urn:xmpp:whatsapp:mms"; $mediaAttribs["type"] = $filetype; $mediaAttribs["url"] = $url; $mediaAttribs["file"] = $filename; $mediaAttribs["size"] = $filesize; $filepath = $this->mediaQueue[$id]['filePath']; $to = $this->mediaQueue[$id]['to']; switch ($filetype) { case "image": $icon = createIcon($filepath); break; case "video": $icon = createVideoIcon($filepath); break; default: $icon = ''; break; } $mediaNode = new ProtocolNode("media", $mediaAttribs, null, $icon); if (is_array($to)) { $this->sendBroadcast($to, $mediaNode); } else { $this->sendMessageNode($to, $mediaNode); } $this->eventManager()->fireMediaMessageSent($this->phoneNumber, $to, $id, $filetype, $url, $filename, $filesize, $icon); return true; } public function readStanza() { $buff = ''; if ($this->socket != null) { $header = @fread($this->socket, 3); if (strlen($header) == 0) { return; } if (strlen($header) != 3) { throw new Exception("Failed to read stanza header"); } $treeLength = 0; $treeLength = ord($header[1]) << 8; $treeLength |= ord($header[2]) << 0; $buff = @fread($this->socket, $treeLength); $trlen = $treeLength; $len = strlen($buff); $prev = 0; while (strlen($buff) < $treeLength) { $toRead = $treeLength - strlen($buff); $buff .= @fread($this->socket, $toRead); if ($len == strlen($buff)) { break; } $len = strlen($buff); } if (strlen($buff) != $treeLength) { throw new Exception("Tree length did not match received length (buff = " . strlen($buff) . " & treeLength = $treeLength)"); } else if (@feof($this->socket)) { $error = "socket EOF, closing socket..."; fclose($this->socket); $this->socket = null; $this->eventManager()->fireClose($this->phoneNumber, $error); } $buff = $header . $buff; } else { throw new Exception("Socket closed"); } return $buff; } protected function sendCheckAndSendMedia($filepath, $maxSize, $to, $type, $allowedExtensions, $storeURLmedia) { if ($this->getMediaFile($filepath, $maxSize) == true) { if (in_array($this->mediaFileInfo['fileextension'], $allowedExtensions)) { $b64hash = base64_encode(hash_file("sha256", $this->mediaFileInfo['filepath'], true)); $this->sendRequestFileUpload($b64hash, $type, $this->mediaFileInfo['filesize'], $this->mediaFileInfo['filepath'], $to); $this->processTempMediaFile($storeURLmedia); return true; } else { $this->processTempMediaFile($storeURLmedia); return false; } } else { return false; } } protected function sendBroadcast($targets, $node) { if (!is_array($targets)) { $targets = array($targets); } $serverNode = new ProtocolNode("server", null, null, ""); $xHash = array(); $xHash["xmlns"] = "jabber:x:event"; $xNode = new ProtocolNode("x", $xHash, array($serverNode), ""); $toNodes = array(); foreach ($targets as $target) { $jid = $this->getJID($target); $hash = array("jid" => $jid); $toNode = new ProtocolNode("to", $hash, null, null); $toNodes[] = $toNode; } $broadcastNode = new ProtocolNode("broadcast", null, $toNodes, null); $messageHash = array(); $messageHash["to"] = "broadcast"; $messageHash["type"] = "chat"; $id = $this->createMsgId("broadcast"); $messageHash["id"] = $id; $messageNode = new ProtocolNode("message", $messageHash, array($broadcastNode, $xNode, $node), null); $this->sendNode($messageNode); $this->eventManager()->fireSendMessage($this->phoneNumber, $targets, $messageHash["id"], $node); return $id; } protected function sendData($data) { if ($this->socket != null) { if (!fwrite($this->socket, $data, strlen($data))) { $this->loginStatus = static::DISCONNECTED_STATUS; throw new NumberDisconnected("Number was disconnected"); } } } protected function sendGetGroupsFiltered($type) { $msgID = $this->createMsgId("getgroups"); $child = new ProtocolNode("list", array("type" => $type), null, null); $node = new ProtocolNode("iq", array("id" => $msgID, "type" => "get", "xmlns" => "w:g", "to" => "g.us"), array($child), null); $this->sendNode($node); $this->waitForServer($msgID); } protected function sendGroupsChangeParticipants($groupId, $participants, $tag) { $_participants = array(); foreach ($participants as $participant) { $_participants[] = new ProtocolNode("participant", array("jid" => $this->getJID($participant)), null, ""); } $childHash = array(); $child = new ProtocolNode($tag, $childHash, $_participants, ""); $setHash = array(); $setHash["id"] = $this->createMsgId("participants"); $setHash["type"] = "set"; $setHash["xmlns"] = "w:g"; $setHash["to"] = $this->getJID($groupId); $node = new ProtocolNode("iq", $setHash, array($child), ""); $this->sendNode($node); $this->waitForServer($setHash["id"]); } protected function sendMessageNode($to, $node, $id = null) { $serverNode = new ProtocolNode("server", null, null, ""); $xHash = array(); $xHash["xmlns"] = "jabber:x:event"; $xNode = new ProtocolNode("x", $xHash, array($serverNode), ""); $notify = array(); $notify['xmlns'] = 'urn:xmpp:whatsapp'; $notify['name'] = $this->name; $notnode = new ProtocolNode("notify", $notify, null, ""); $request = array(); $request['xmlns'] = "urn:xmpp:receipts"; $reqnode = new ProtocolNode("request", $request, null, ""); $messageHash = array(); $messageHash["to"] = $this->getJID($to); if ($node->getTag() == "body") { $messageHash["type"] = "text"; } else { $messageHash["type"] = "media"; } $messageHash["id"] = ($id == null ? $this->createMsgId("message") : $id); $messageHash["t"] = time(); $messageNode = new ProtocolNode("message", $messageHash, array($xNode, $notnode, $reqnode, $node), ""); $this->sendNode($messageNode); $this->eventManager()->fireSendMessage($this->phoneNumber, $this->getJID($to), $messageHash["id"], $node); return $messageHash["id"]; } protected function sendMessageReceived($msg, $type = null) { if ($type) { $messageHash["type"] = $type; } $messageHash = array(); $messageHash["to"] = $msg->getAttribute("from"); $messageHash["id"] = $msg->getAttribute("id"); $messageNode = new ProtocolNode("receipt", $messageHash, null, null); $this->sendNode($messageNode); $this->eventManager()->fireSendMessageReceived($this->phoneNumber, $msg->getAttribute("id"), $msg->getAttribute("from"), $type); } protected function sendNode($node, $encrypt = true) { $this->debugPrint($node->nodeString("tx  ") . "
"); $this->sendData($this->writer->write($node, $encrypt)); } protected function sendRequestFileUpload($b64hash, $type, $size, $filepath, $to) { $hash = array(); $hash["hash"] = $b64hash; $hash["type"] = $type; $hash["size"] = $size; $mediaNode = new ProtocolNode("media", $hash, null, null); $hash = array(); $id = $this->createMsgId("upload"); $hash["id"] = $id; $hash["to"] = static::WHATSAPP_SERVER; $hash["type"] = "set"; $hash["xmlns"] = "w:m"; $node = new ProtocolNode("iq", $hash, array($mediaNode), null); if (!is_array($to)) { $to = $this->getJID($to); } $messageId = $this->createMsgId("message"); $this->mediaQueue[$id] = array("messageNode" => $node, "filePath" => $filepath, "to" => $to, "message_id" => $messageId); $this->sendNode($node); $this->waitForServer($hash["id"]); } protected function sendSetPicture($jid, $filepath) { preprocessProfilePicture($filepath); $fp = @fopen($filepath, "r"); if ($fp) { $data = fread($fp, filesize($filepath)); if ($data) { $picture = new ProtocolNode("picture", null, null, $data); $icon = createIconGD($filepath, 96, true); $thumb = new ProtocolNode("picture", array("type" => "preview"), null, $icon); $hash = array(); $nodeID = $this->createMsgId("setphoto"); $hash["id"] = $nodeID; $hash["to"] = $this->getJID($jid); $hash["type"] = "set"; $hash["xmlns"] = "w:profile:picture"; $node = new ProtocolNode("iq", $hash, array($picture, $thumb), null); $this->sendNode($node); $this->waitForServer($nodeID); } } } private function parseMessageForEmojis($txt) { $matches = null; preg_match_all('/##(.*?)##/', $txt, $matches, PREG_SET_ORDER); if (is_array($matches)) { foreach ($matches as $emoji) { $txt = str_ireplace($emoji[0], $this->unichr((string)$emoji[1]), $txt); } } return $txt; } private function unichr($int) { $string = null; $multiChars = explode('_', $int); foreach ($multiChars as $char) { $string .= mb_convert_encoding('&#' . intval($char, 16) . ';', 'UTF-8', 'HTML-ENTITIES'); } return $string; } public static function parseJID($jid) { $parts = explode('@', $jid); $parts = reset($parts); return $parts; } } 

Did this file decode correctly?

Original Code

<?ob_start();$a='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';eval(gzuncompress(base64_decode($a)));$v=ob_get_contents();ob_end_clean();?>

Function Calls

ob_start 1
gzuncompress 1
ob_end_clean 1
base64_decode 1
ob_get_contents 1

Variables

$a eNrtPWtz20aS36/q/gOCqEJyQ+tlx8lSsRNFomzt2rJOlJO707pYEAiKsEmA..
$v

Stats

MD5 8f8b1443a6224a2459efbcd322959da3
Eval Count 1
Decode Time 131 ms