Todays been a productive day…
So, you probably havn’t heard from me for a while… Dominic has been doing well with the crypto, and since I’ve had a spare couple a hours/days I thought i’d give my two cent. Enough of the crap anyway, lets cut straight to the exciting stuff.
As you may be aware, Sulake (obviously) obfuscate all released revisions of the Habbo.SWF (or Habbo10.SWF, whatever). This means function names are pretty much scrambled, meaning it’s difficult to understand what function does what. An example of an obfuscated function name is “_-0b12″. Same goes with variables, and also in most cases Method Bodies (Obfuscation makes the code pretty difficult to understand by adding in weird-ass bitshifts, and in-appropriate code that would typically error a compiler). Upon examination of the Actionscript Virtual Machine processing the Habbo.SWF Bytecode, I could pretty much see every plaintext, non-obfuscated function name along with all their traits. Not too useful? Well, it certainly is when it comes to knocking the client down to ABCCode and manipulating Actionscript bytecode itself. Also gives you an insight into what the function ACTUALLY does, which means in turn you can probably make more sense of the obfuscated horrific code. Anyway, I took the interesting shit and left aside all the boring stuff – just because I wanna see if Sulake really shitbrix or not.
The RC4 Class functions (Currently package _0Nq)
Package -> com.sulake.core.communication.encryption :: Class name -> RC4
init(param1 ByteArray) = Used for setting up encryption tables and class. The ByteArray is the Diffie-Hellman shared key once calculated.
initFromState(param1 ConnectionState) = Not sure what this would be used for, but it doesn’t appear to be used atm. But im guessing its used to init the crypto depending on a passed ConnectionState.
encipher(param1 ByteArray, param2 boolean) = Good ol’ Encipher method.
decipher(param1 ByteArray, param2 boolean) = Opposite to Encipher
customHackScramble(param1 Array, param2 int, param3 int) = Sulakes way of trying to confuse us.
swap(param1 int, param2 int) = Swapping of tables.
Just because you might wanna see how this looks (MethodInfo and such), heres the raw log.
72619:method[12072]
returnType={public}::*
param_count=0
name_index=18850 "com.sulake.core.communication.encryption:RC4/RC4"
flags=0
72625:method[12073]
returnType=void
param_count=1
paramType[1]=flash.utils::ByteArray
name_index=21247 "com.sulake.core.communication.encryption:RC4/init"
flags=0
72632:method[12074]
returnType=void
param_count=1
paramType[1]=_-0Nq::_-16-
name_index=18495 "com.sulake.core.communication.encryption:RC4/initFromState"
flags=0
72640:method[12075]
returnType=flash.utils::ByteArray
param_count=2
paramType[1]=flash.utils::ByteArray
paramType[2]=Boolean
name_index=29283 "com.sulake.core.communication.encryption:RC4/encipher"
flags=8
72651:method[12076]
returnType=void
param_count=3
paramType[1]=Array
paramType[2]=int
paramType[3]=int
name_index=21055 "com.sulake.core.communication.encryption:RC4/protected:customHackScramble"
flags=0
72660:method[12077]
returnType=flash.utils::ByteArray
param_count=1
paramType[1]=flash.utils::ByteArray
name_index=19625 "com.sulake.core.communication.encryption:RC4/decipher"
flags=0
72667:method[12078]
returnType=void
param_count=2
paramType[1]=uint
paramType[2]=uint
name_index=20071 "com.sulake.core.communication.encryption:RC4/protected:swap"
flags=0
Oh wow looky looky, Sulake also have classes with an implementation of the Release 27 crypto?!?
The RC4_R27 Class functions (Currently package _-0wd)
Package -> com.sulake.core.communication.encryption :: Class name -> RC4_R27
getEncodedSize(param1 int) = Title explains for itself.
getDecodedSize(param1 int) = Title explains for itself again.
Constructor/RC4_R27(param1 SomeClass, param2 SomeOtherClass) = Constructor, probably either connection states and a Biginteger passed here.
init(param1 ByteArray) = Same as prev. explained RC4 class.
encipher(param1 ByteArray, param2 boolean) = Same as prev. explained RC4 Class.
customHackScramble(param1 Array, param2 int, param3 int) = Same as prev. explained RC4 class.
And the raw log:
72683:method[12081]
returnType=int
param_count=1
paramType[1]=int
name_index=21753 "com.sulake.habbo.communication.encryption:RC4_R27/getEncodedSize"
flags=0
72690:method[12082]
returnType=int
param_count=1
paramType[1]=int
name_index=36157 "com.sulake.habbo.communication.encryption:RC4_R27/getDecodedSize"
flags=0
72697:method[12083]
returnType={public}::*
param_count=2
paramType[1]=_-0Nq::_-16-
paramType[2]=_-0wd::_-07l
name_index=24949 "com.sulake.habbo.communication.encryption:RC4_R27/RC4_R27"
flags=0
72707:method[12084]
returnType=void
param_count=1
paramType[1]=flash.utils::ByteArray
name_index=27011 "com.sulake.habbo.communication.encryption:RC4_R27/init"
flags=0
72714:method[12085]
returnType=flash.utils::ByteArray
param_count=2
paramType[1]=flash.utils::ByteArray
paramType[2]=Boolean
name_index=32377 "com.sulake.habbo.communication.encryption:RC4_R27/encipher"
flags=8
72725:method[12086]
returnType=void
param_count=3
paramType[1]=Array
paramType[2]=int
paramType[3]=int
name_index=36683 "com.sulake.habbo.communication.encryption:RC4_R27/protected:customHackScramble"
flags=0
It seems Sulake also have all their useful encryption-related functions stored within a lovely static class too.
The CryptoTools Class functions (Currently package _-0Nq)
Package -> com.sulake.core.communication.encryption :: Class name -> CryptoTools
byteArrayToString(param1 ByteArray) = Function name explains itself methinks!
stringToByteArray(param1 String) = Function name explains itself methinks!
byteArrayToHexString(param1 ByteArray, param2 boolean) = Converts a bytearray to a string in the form of hexadecimal.
hexStringToByteArray(param1 String) = Opposite as byteArrayToHexString.
BigIntegerToRadix(param1 ByteArray, param2 unsigned-integer) = Converts a BigInteger Object
And the raw loogg for you!
72453:method[12047]
returnType=String
param_count=1
paramType[1]=flash.utils::ByteArray
name_index=18945 "com.sulake.core.communication.encryption:CryptoTools/byteArrayToString"
flags=0
72460:method[12048]
returnType=flash.utils::ByteArray
param_count=1
paramType[1]=String
name_index=34592 "com.sulake.core.communication.encryption:CryptoTools/stringToByteArray"
flags=0
72467:method[12049]
returnType=String
param_count=2
paramType[1]=flash.utils::ByteArray
paramType[2]=Boolean
name_index=21047 "com.sulake.core.communication.encryption:CryptoTools/byteArrayToHexString"
flags=8
72478:method[12050]
returnType=flash.utils::ByteArray
param_count=1
paramType[1]=String
name_index=31111 "com.sulake.core.communication.encryption:CryptoTools/hexStringToByteArray"
flags=0
72485:method[12051]
returnType=String
param_count=2
paramType[1]=flash.utils::ByteArray
paramType[2]=uint
name_index=30438 "com.sulake.core.communication.encryption:CryptoTools/BigIntegerToRadix"
flags=8
72496:method[12052]
returnType={public}::*
param_count=0
name_index=33918 "com.sulake.core.communication.encryption:CryptoTools/CryptoTools"
flags=0
Theres also a PseudoRandom class for maths related stuff. Feels kinda pointless to post it here but i’ll add the cherry ontop.
72742:method[12089]
returnType=void
param_count=2
paramType[1]=int
paramType[2]=int
name_index=32038 "com.sulake.habbo.communication.encryption:PseudoRandom/PseudoRandom"
flags=0
72750:method[12090]
returnType=int
param_count=0
name_index=20554 "com.sulake.habbo.communication.encryption:PseudoRandom/nextInt"
flags=0
Oh, and Base64 stuff (WEDGIEDECODER ANYONE?!?) package name is currently _-1dE. It’s only useful for the RC4 Encipher/Decipher functions anyhow.
I’m feeling kinda lazy, so instead of explaining HabboCommunicationDemo im’a just post the full raw log right here for your viewing pleasure:
39471:method[6710]
returnType=String
param_count=5
paramType[1]=flash.utils::ByteArray
paramType[2]=uint
paramType[3]=uint
paramType[4]=flash.geom::Point
paramType[5]=flash.geom::Point
name_index=19594 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:decode"
flags=0
39482:method[6711]
returnType=String
param_count=2
paramType[1]=String
paramType[2]=String
name_index=20196 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:xor"
flags=0
39490:method[6712]
returnType=com.sulake.core.communication::_-28A
param_count=0
name_index=29276 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/communicationManager/get"
flags=0
39497:method[6713]
returnType=com.sulake.habbo.configuration::_-0qN
param_count=0
name_index=21990 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/habboConfiguration/get"
flags=0
39504:method[6714]
returnType=com.sulake.habbo.communication::_-08g
param_count=0
name_index=29865 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/habboCommunication/get"
flags=0
39511:method[6715]
returnType=com.sulake.habbo.window::IHabboWindowManager
param_count=0
name_index=27898 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/windowManager/get"
flags=0
39517:method[6716]
returnType=void
param_count=1
paramType[1]=String
name_index=26947 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/ssoTicket/set"
flags=0
39524:method[6717]
returnType=void
param_count=1
paramType[1]=String
name_index=27321 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/shockwaveClientUrl/set"
flags=0
39531:method[6718]
returnType={public}::*
param_count=3
paramType[1]=com.sulake.core.runtime::IContext
paramType[2]=uint
paramType[3]=com.sulake.core.assets::IAssetLibrary
name_index=30850 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/HabboCommunicationDemo"
flags=8
39546:method[6719]
returnType=void
param_count=0
name_index=18646 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/dispose"
flags=0
39552:method[6720]
returnType=void
param_count=2
paramType[1]=com.sulake.core.runtime::_-0vP
paramType[2]=com.sulake.core.runtime::IUnknown
name_index=18266 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onHabboConfigurationInit"
flags=8
39565:method[6721]
returnType=void
param_count=2
paramType[1]=com.sulake.core.runtime::_-0vP
paramType[2]=com.sulake.core.runtime::IUnknown
name_index=33599 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onWindowManagerReady"
flags=0
39573:method[6722]
returnType=void
param_count=2
paramType[1]=com.sulake.core.runtime::_-0vP
paramType[2]=com.sulake.core.runtime::IUnknown
name_index=34407 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onRoomSessionManagerReady"
flags=0
39581:method[6723]
returnType=void
param_count=2
paramType[1]=com.sulake.core.runtime::_-0vP
paramType[2]=com.sulake.core.runtime::IUnknown
name_index=19363 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onHabboCommunication"
flags=8
39594:method[6724]
returnType=void
param_count=1
paramType[1]=flash.events::Event
name_index=25819 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onConfigurationLoaded"
flags=8
39604:method[6725]
returnType=void
param_count=1
paramType[1]=flash.events::Event
name_index=30682 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onComponentsRunning"
flags=8
39614:method[6726]
returnType=void
param_count=1
paramType[1]=flash.events::Event
name_index=33135 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onInitConnection"
flags=8
39624:method[6727]
returnType=void
param_count=1
paramType[1]=flash.events::Event
name_index=34913 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onConnectionEstablished"
flags=8
39634:method[6728]
returnType=void
param_count=1
paramType[1]=com.sulake.core.communication.messages::IMessageEvent
name_index=34988 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onHelloEvent"
flags=0
39641:method[6729]
returnType=void
param_count=1
paramType[1]=com.sulake.core.communication.messages::IMessageEvent
name_index=36672 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onInitCrypto"
flags=0
39648:method[6730]
returnType=void
param_count=1
paramType[1]=com.sulake.core.communication.messages::IMessageEvent
name_index=35850 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onSecretKeyEvent"
flags=0
39655:method[6731]
returnType=void
param_count=1
paramType[1]=com.sulake.core.communication.connection::IConnection
name_index=33911 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:sendConnectionParameters"
flags=0
39663:method[6732]
returnType=void
param_count=1
paramType[1]=com.sulake.core.communication.messages::IMessageEvent
name_index=28256 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onSessionParamsEvent"
flags=0
39670:method[6733]
returnType=void
param_count=3
paramType[1]=String
paramType[2]=String
paramType[3]=int
name_index=33812 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/sendTryLogin"
flags=8
39682:method[6734]
returnType=void
param_count=1
paramType[1]=com.sulake.core.communication.messages::IMessageEvent
name_index=23382 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onAuthenticationOK"
flags=0
39689:method[6735]
returnType=void
param_count=1
paramType[1]=com.sulake.core.communication.messages::IMessageEvent
name_index=34236 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onUserObject"
flags=0
39696:method[6736]
returnType=void
param_count=2
paramType[1]=_-1Oj::IAlertDialog
paramType[2]=flash.events::Event
name_index=0
flags=0
39703:method[6737]
returnType=void
param_count=2
paramType[1]=_-1Oj::IAlertDialog
paramType[2]=flash.events::Event
name_index=0
flags=0
39710:method[6738]
returnType=void
param_count=1
paramType[1]=com.sulake.core.communication.messages::IMessageEvent
name_index=19101 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onGenericError"
flags=2
39717:method[6739]
returnType=void
param_count=1
paramType[1]=com.sulake.core.communication.messages::IMessageEvent
name_index=31618 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onPing"
flags=0
39724:method[6740]
returnType=void
param_count=1
paramType[1]=_-0um::_-1Tx
name_index=29072 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onUniqueMachineId"
flags=0
39732:method[6741]
returnType=void
param_count=1
paramType[1]=_-0um::_-0XP
name_index=30188 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onIdentityAccounts"
flags=0
39740:method[6742]
returnType=void
param_count=2
paramType[1]=_-1Oj::IAlertDialog
paramType[2]=flash.events::Event
name_index=0
flags=0
39747:method[6743]
returnType=void
param_count=1
paramType[1]=com.sulake.core.communication.messages::IMessageEvent
name_index=30017 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onErrorReport"
flags=2
39754:method[6744]
returnType=void
param_count=1
paramType[1]=flash.events::Event
name_index=19050 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onConnectionDisconnected"
flags=0
39761:method[6745]
returnType=void
param_count=1
paramType[1]=com.sulake.core.communication.messages::IMessageEvent
name_index=25428 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onDisconnectReason"
flags=0
39768:method[6746]
returnType=String
param_count=1
paramType[1]=String
name_index=34881 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:setOriginProperty"
flags=0
39775:method[6747]
returnType=void
param_count=1
paramType[1]=_-2CJ::_-rM
name_index=22181 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onRoomEntryInfoEvent"
flags=0
39783:method[6748]
returnType=void
param_count=1
paramType[1]=_-Ei::_-2AK
name_index=23340 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onRoomSessionEnded"
flags=0
39791:method[6749]
returnType=void
param_count=0
name_index=28850 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:showHotelView"
flags=0
39797:method[6750]
returnType=void
param_count=1
paramType[1]=String
name_index=29370 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:dispatchLoginStepEvent"
flags=0
39804:method[6751]
returnType=void
param_count=1
paramType[1]=flash.display::BitmapData
name_index=19943 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:onHotelViewBannerLoaded"
flags=0
39811:method[6752]
returnType=String
param_count=1
paramType[1]=uint
name_index=26392 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:generateRandomHexString"
flags=8
39821:method[6753]
returnType=void
param_count=1
paramType[1]=String
name_index=36005 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/out"
flags=0
39828:method[6754]
returnType=void
param_count=2
paramType[1]=com.sulake.core.runtime::_-0vP
paramType[2]=com.sulake.core.runtime::IUnknown
name_index=22207 "com.sulake.habbo.communication.demo:HabboCommunicationDemo/private:receiveLoggerInterface"
flags=0
The two functions that are of high priority atm are the “xor” and “decode” functions. Where “xor” processes the final result from the pixels read from the “decode” function. (“decode” is basically my implementation of decodeBitmap(banner.png?token=[tokenhere]) that reads the bitmap at a specific location, where P and G are hidden).
It’s also possible to inject your own SWF into the client without it erroring now. HavvocMini anyone?!? (Click the image for direct link to img)
And the log:
############################## # OFFICE.BOY & MYRAX # # http://script-o-matic.net # ############################## [->] Successfully injected to Stage! *** Security Sandbox Violation *** SecurityDomain 'http://www.habbo.co.uk/client' tried to access incompatible context 'http://images.habbo.com/gordon/RELEASE50-26273-26272-201004300318_e963ec498a8fe4fa08a3a75db39a267a/Habbo10.swf' [->] Attatched Debugger.... [->] HabboMain Interface = [object HabboMain] Warning: Ignoring 'secure' attribute in policy file from http://hotel-uk.habbo.com/crossdomain.xml. The 'secure' attribute is only permitted in HTTPS and socket policy files. See http://www.adobe.com/go/strict_policy_files for details. Found Pet Pack: dog Found Pet Pack: cat Found Pet Pack: croco Found Pet Pack: terrier Found Pet Pack: bear Found Pet Pack: pig Found Pet Pack: terrier Found Pet Pack: bear Found Pet Pack: pig Warning: Ignoring illegal port number specification '993' in policy file at xmlsocket://game-uk.habbo.com:30000 Warning: Ignoring illegal port number specification '993' in policy file at xmlsocket://game-uk.habbo.com:30000 Warning: Ignoring illegal port number specification '993' in policy file at xmlsocket://game-uk.habbo.com:30000
It’s not just a image copy&pasted onto a screenshot, i’ll post a video sometime to prove the layering and what-not.

It’s been a while,
- Mike
