[Basics Tutorial] - [Hacked Clients]

Posts 1–15 of 25 · Page 1 of 2
[Basics Tutorial] - [Hacked Clients]
Want to learn to make hacked clients? Want to contribute to our lovely community instead of just leeching. It'll take just a while to learn the basics, just start by following this guide!

Chapter 1 - Getting a fresh client

First you need to get the new version number. It'll be available over here: www.realmofthemadgod.com/version.txt
Copy the version number and go to this link: www.realmofthemadgod.com/AssembleeGameClient[version].swf
Replace the [version] with the series of numbers what you got from the version.txt.
For the current 19.1 client the link is: http://www.realmofthemadgod.com/Asse...1389653812.swf
When the page has loaded press Ctrl + S to save the page to your computer.

Chapter 2 - Connecting to production

You'll notice that the client connects to testing. Don't panic, that is normal. We need to add the connect to production mod but first you need to decompile the frest client, but you also need a client for the earlier build where you'll be updating the _-names and line numbers from.

For this tutorial I'll use 19.0 Mod selector as the one where I'm updating the _-names and line numbers from. I'll update them to work with newest 19.1 client.

So now for the decompiling, it'll be easiest if you used batch scripts to help you. Open notepad and paste this code in:
Code:
swfdecompress.exe client191.swf
abcexport.exe client191.swf
rabcdasm.exe client191-1.abc
pause
Save it as Decompile.bat for example. Do not forget to add the .bat extension. Place your RABCDAsm folder and rename the fresh client that you downloaded from the official website to client191.swf. Then run Decompile.bat.

Next edit the Decompile.bat to look like this, for example:
Code:
swfdecompress.exe client190.swf
abcexport.exe client190.swf
rabcdasm.exe client190-1.abc
pause
And get the 19.0 client from here. Next place it in your RABCDAsm folder and rename it to client190.swf and run the batch script again. It's good to give the clients a name that has their version number in it.

Open the following folder in the Mod selector you downloaded *\19.0_Mod_Selector\mods\19.0.0_prod and open 19.0.0_prod.xml with your preferred text editor. I'd recommend you to download Notepad++, as it makes your life easier.

You'll see this:
Code:
<?xml version="1.0" encoding="UTF-8"?>

<rotmg>
	<mod id="Connect to Production Server">
		<code file2mod="_-x5\_-1Wb.class.asasm" 
			  line="498">
			prod.txt
		</code>
	</mod>
</rotmg>
Now open the file that it says (*\client190\_-x5\_-1Wb.class.asasm). Now you need to find the same file from the new 19.1 client but wait. You'll only see that there is no folder called _-x5 in the 19.1 client. Now you need a program called AstroGrep. Download it if you haven't already and change the search path to point to the 19.1 client's folder (*\client191) and search from the already open _-1Wb.class.asasm file an unusual bit of code. I chose line number 601 and entered QName(PackageNamespace("flash.net"), "LocalConnection") in AstroGrep's search text field. Notice that if AstroGrep gives you long list of results, you may want to choose something else than that part of code.

Press the search button and let it go through the files in *\client191 folder. It should find the following matches if you're using 19.1 client:
Code:
Memory.class.asasm
_-pk.class.asasm
_-Ek.class.asasm
_-1oC.class.asasm
Look at the right most colon on AstroGrep which says "Count". Now you should go back to Notepad++ where you have _-1Wb.class.asasm open. Press Ctrl + F and write there the part that you chose to look for. I wrote QName(PackageNamespace("flash.net"), "LocalConnection") on the search field as I chose that when we were deciding on an unusual part of code. Press count to see the number of matches in the document. It says that there is 3 matches for QName(PackageNamespace("flash.net"), "LocalConnection") in _-1Wb.class.asasm. That makes the number of possibilities smaller. Notice the new file may not always have same amount of matches. Now we have only 2 potential matches for that file:
Code:
_-pk.class.asasm
_-1oC.class.asasm
Now that there is only few possibilities we can search if they match manually. Open both of those files in Notepad++. Start scrolling all the files at nearly same speeds. You'll see that _-pk has part that catches eye:
Code:
  trait slot QName(PrivateNamespace("*", "_-0o8:_-pk/instance#0"), "_callbacks") type QName(PackageNamespace("", "#0"), "Object") end
  trait slot QName(PrivateNamespace("*", "_-0o8:_-pk/instance#0"), "_mode") type QName(PackageNamespace("", "#0"), "uint") end
  trait slot QName(PrivateNamespace("*", "_-0o8:_-pk/instance#0"), "_-0Jq") type QName(PackageNamespace("flash.net"), "LocalConnection") end
  trait slot QName(PrivateNamespace("*", "_-0o8:_-pk/instance#0"), "_-Pq") type QName(PackageNamespace("flash.net"), "Socket") end
  trait slot QName(PrivateNamespace("*", "_-0o8:_-pk/instance#0"), "_-dr") type QName(PackageNamespace("flash.utils"), "ByteArray") end
  trait slot QName(PrivateNamespace("*", "_-0o8:_-pk/instance#0"), "_-0Go") type QName(PackageNamespace("", "#0"), "Object") end
  trait slot QName(PrivateNamespace("*", "_-0o8:_-pk/instance#0"), "_-0cE") type QName(PackageNamespace("flash.utils"), "Dictionary") end
  trait slot QName(PrivateNamespace("*", "_-0o8:_-pk/instance#0"), "_-oh") type QName(PackageNamespace("", "#0"), "String") value Utf8("") end
  trait slot QName(PrivateNamespace("*", "_-0o8:_-pk/instance#0"), "_-nB") type QName(PackageNamespace("", "#0"), "Boolean") end
  trait slot QName(PrivateNamespace("*", "_-0o8:_-pk/instance#0"), "_-rh") type QName(PackageNamespace("", "#0"), "String") end
  trait slot QName(PrivateNamespace("*", "_-0o8:_-pk/instance#0"), "_-1c4") type QName(PackageNamespace("", "#0"), "String") end
If you scroll the _-1Wb.class.asasm down you'll notice that there is no such part in there.

In _-1oC.class.asasm this part catches my eye:
Code:
  trait slot QName(PackageNamespace("", "#0"), "loaderInfo") flag METADATA type QName(PackageNamespace("flash.display"), "LoaderInfo")
   metadata "Inject"
   end ; metadata
  end ; trait
  trait slot QName(PackageNamespace("", "#0"), "_-0Dx") flag METADATA type QName(PackageNamespace("_-Pg"), "_-1Tf")
   metadata "Inject"
   end ; metadata
  end ; trait
  trait slot QName(PrivateNamespace("*", "_-Pg:_-1oC"), "_-A2") type QName(PackageNamespace("", "#0"), "Boolean") value False() end
  trait slot QName(PrivateNamespace("*", "_-Pg:_-1oC"), "_-0Hv") type QName(PackageNamespace("_-0z8"), "_-LZ") end
  trait method QName(PackageNamespace("", "#0"), "_-0lh")
Again if you scroll the _-1Wb.class.asasm to about same area you'll see quite much similar code:
Code:
  trait slot QName(PackageNamespace("", "#0"), "loaderInfo") flag METADATA type QName(PackageNamespace("flash.display"), "LoaderInfo")
   metadata "Inject"
   end ; metadata
  end ; trait
  trait slot QName(PackageNamespace("", "#0"), "_-0o6") flag METADATA type QName(PackageNamespace("_-x5"), "_-OQ")
   metadata "Inject"
   end ; metadata
  end ; trait
  trait slot QName(PrivateNamespace("*", "_-x5:_-1Wb"), "_-mp") type QName(PackageNamespace("", "#0"), "Boolean") value False() end
  trait slot QName(PrivateNamespace("*", "_-x5:_-1Wb"), "_-XM") type QName(PackageNamespace("_-1mW"), "_-1Y8") end
  trait method QName(PackageNamespace("", "#0"), "_-5B")
The newer _-name for _-1Wb.class.asasm is _-1oC.class.asasm!

Now scroll to line number 498 in _-1Wb.class.asasm because the 19.0.0_prod.xml had that line marked down there. Then scroll in the _-1oC.class.asasm to about same lines of code and search for matches on surrounding code. You'll notice that line number 489 in _-1oC.class.asasm matches with the line number 498 in _-Wb.class.asasm. Check it for yourself they look really similar based on the surroundings.

The newer line number for 498 (_-1Wb.class.asasm) is 489 (_-1oC.class.asasm)!

Now you can edit the_-1oC.class.asasm by inserting a new row after line number 489 and copying the code from prod.txt which locates in same folder with 19.0.0_prod.xml. Insert the copied code on the new line you created (490). Make sure to open prod.txt with Notepad++ to prevent errors caused by regular notepad.

Save the modification and go back to your RABCDAsm folder. Create a new batch script:
Code:
rabcasm.exe client191-1\client191-1.main.asasm
abcreplace.exe client191.swf 1 client191-1\client191-1.main.asasm
pause
Save it as Recompile.bat, for example, and run it. After it has completed recompiling the client191.swf test if your client connects to production.

Chapter 3 - Auto-Nexus

Open the mods folder on the mod selector and locate 19.0.0_autoNexus folder. Open 19.0.0_autoNexus.xml and you'll see this:
Code:
<?xml version="1.0" encoding="UTF-8"?>

<rotmg>
	<mod id="Auto-Nexus 20 Percent">
		<code file2mod="com/company/assembleegameclient/objects/Player.class.asasm"
			  line="4982">
			19.0.0_autoNexus_20.txt
		</code>
	</mod>
		<mod id="Auto-Nexus 30 Percent">
		<code file2mod="com/company/assembleegameclient/objects/Player.class.asasm"
			  line="4982">
			19.0.0_autoNexus_30.txt
		</code>
	</mod>
		<mod id="Auto-Nexus 40 Percent">
		<code file2mod="com/company/assembleegameclient/objects/Player.class.asasm"
			  line="4982">
			19.0.0_autoNexus_40.txt
		</code>
	</mod>
</rotmg>
There you'll see 3 different mods are added to the Mod selector list within this file. They're all auto-nexuses so no one uses them all at once. Pick just one of them, it doesn't really matter. Open the file where the mod needs to be added (*\client190\com\company\assembleegameclient\objec ts\Player.class.asasm). This time it will be the same file in the new 19.1 client, because the name of the file that needs to be modded is not a _-name. So this time you can also open the other file (*\client191\com\company\assembleegameclient\objec ts\Player.class.asasm) without any further searching.

Now in the 19.0 client's Player.class.asasm locate line number 4982 and pick some unusual part of code near line 4982. I picked this part of code from line 4978:
Code:
      setproperty         QName(PackageNamespace("", "#0"), "lastDamage_")
I searched how many matches are there for "lastDamage_" in 19.0 client's Player.class.asasm. Again I pressed Ctrl + F and put lastDamage_ in the search box and then pressed Count. There are 2 matches so I scrolled back to beginning of the file and searched for that again to see is it the first or second match that the place for auto-nexus code is near. This time it was the second match so I opened 19.1 client's Player.class.asasm and searched for the second match for lastDamage_ by pressing Ctrl + F and then pressing two times "Find next" button.

Now we can recognize that the code there looks nearly same as in the older Player.class.asasm so we are able to say that line number 4932 is the new line for auto-nexus code.

Next open file called 19.0.0_autoNexus_30.txt and you should see this:
Code:
; _-names
#set charHp "_-0Ie"
#set charMaxHp "_-0sG"
#set funcEscape "escape"

; code
	pop
	getlocal0
	getlex              QName(PackageNamespace(""), "map_")
	getproperty         QName(PackageNamespace(""), "player_")
	ifne				END
	
	getlex              QName(PackageNamespace(""), "map_")
	getproperty         QName(PackageNamespace(""), "name_")
	pushstring			"Nexus"
	ifeq				END
	
	getlex              QName(PackageNamespace(""), "map_")
	getproperty         QName(PackageNamespace(""), "name_")
	pushstring			"Arena"
	ifeq				END
	
	getlex				QName(PackageNamespace(""), $"charHp")
	getlex				QName(PackageNamespace(""), $"charMaxHp")
	convert_d
	divide
	pushdouble 			.3
	ifgt				END
	getlex              QName(PackageNamespace(""), "map_")
	getproperty         QName(PackageNamespace(""), "gs_")
	getproperty         QName(PackageNamespace(""), "gsc_")
	callpropvoid        QName(PackageNamespace(""), $"funcEscape"), 0
END:
	pushtrue
The part we're interested in for now is this:
Code:
; _-names
#set charHp "_-0Ie"
#set charMaxHp "_-0sG"
#set funcEscape "escape"
Those are the _-names that the auto-nexus code refers to to make the function to work. Let's start seeking for the new _-names for these. Open up your AstroGrep and set the Search Path to point to the client190 folder. And let's first search for "_-0Ie". We're looking for a match that doesn't have _-name. For me GameObject.class.asasm seems like good match. Open GameObject.class.asasm from both, client190 and client191 folders.

Now search "_-0Ie" from the 19.0 client's GameObject.class.asasm. The first match looks bit hard to play with so I used the second match since there is more code around it to look for from the 19.1 client's GameObject.class.asasm:
Code:
  trait slot QName(ProtectedNamespace("_-1cF"), "_-0B7") type QName(PackageNamespace("flash.display"), "BitmapData") value Null() end
  trait slot QName(ProtectedNamespace("_-1cF"), "_-1g5") type QName(PackageNamespace("flash.utils"), "Dictionary") value Null() end
  trait slot QName(PackageNamespace("", "#0"), "_-0sG") type QName(PackageNamespace("", "#0"), "int") value Integer(200) end
  trait slot QName(PackageNamespace("", "#0"), "_-0Ie") type QName(PackageNamespace("", "#0"), "int") value Integer(200) end
  trait slot QName(PackageNamespace("", "#0"), "size_") type QName(PackageNamespace("", "#0"), "int") value Integer(100) end
Let's choose something that we think helps us to find the new name in the 19.1 client's GameObject.class.asasm. I chose Integer(200) and searched in the 19.1 client's GameObject.class.asasm and found the same code block:
Code:
  trait slot QName(ProtectedNamespace("_-Ko"), "_-0qU") type QName(PackageNamespace("flash.display"), "BitmapData") value Null() end
  trait slot QName(ProtectedNamespace("_-Ko"), "_-NH") type QName(PackageNamespace("flash.utils"), "Dictionary") value Null() end
  trait slot QName(PackageNamespace("", "#0"), "_-0J6") type QName(PackageNamespace("", "#0"), "int") value Integer(200) end
  trait slot QName(PackageNamespace("", "#0"), "_-1nm") type QName(PackageNamespace("", "#0"), "int") value Integer(200) end
  trait slot QName(PackageNamespace("", "#0"), "size_") type QName(PackageNamespace("", "#0"), "int") value Integer(100) end
_-1nm looks to have the same spot in the code as the old _-0Ie. That must be the new _-name! Now we have solved the first one of the names so replace the old one with the new one:
Code:
; _-names
#set charHp "_-1nm"
#set charMaxHp "_-0sG"
#set funcEscape "escape"
The second one of them is quite easy to solve using the same method so now try for yourself. Found it? Good, let's continue. Now it should look like this:
Code:
; _-names
#set charHp "_-1nm"
#set charMaxHp "_-0J6"
#set funcEscape "escape"
funcEscape almost never updates, so no need to worry about it for now. Now you're ready to place the code, but let's first make little modifications to the code:
Code:
; _-names
#set charHp "_-1nm"
#set charMaxHp "_-0J6"
#set funcEscape "escape"

; code
	pop
	getlocal0
	getlex              QName(PackageNamespace(""), "map_")
	getproperty         QName(PackageNamespace(""), "player_")
	ifne				END
	
	getlex              QName(PackageNamespace(""), "map_")
	getproperty         QName(PackageNamespace(""), "name_")
	pushstring			"Nexus"
	ifeq				END
	
	getlex              QName(PackageNamespace(""), "map_")
	getproperty         QName(PackageNamespace(""), "name_")
	pushstring			"Arena"
	ifeq				END
;Here we have the safe areas so let's make a modification and add vault as a safe area because
;it is quite annoying if you connect to vault with low hp and it auto-nexuses you because of that
	
	getlex				QName(PackageNamespace(""), $"charHp")
	getlex				QName(PackageNamespace(""), $"charMaxHp")
	convert_d
	divide
	pushdouble 			.3 ;This one changes the auto-nexus percentage so you can make for example a 25% auto-nexus, now let's try that
	ifgt				END
	getlex              QName(PackageNamespace(""), "map_")
	getproperty         QName(PackageNamespace(""), "gs_")
	getproperty         QName(PackageNamespace(""), "gsc_")
	callpropvoid        QName(PackageNamespace(""), $"funcEscape"), 0
END:
	pushtrue
Now I've modified the code to look like this:
Code:
; _-names
#set charHp "_-1nm"
#set charMaxHp "_-0J6"
#set funcEscape "escape"

; code
	pop
	getlocal0
	getlex              QName(PackageNamespace(""), "map_")
	getproperty         QName(PackageNamespace(""), "player_")
	ifne				END
	
	getlex              QName(PackageNamespace(""), "map_")
	getproperty         QName(PackageNamespace(""), "name_")
	pushstring			"Nexus"
	ifeq				END
	
	getlex              QName(PackageNamespace(""), "map_")
	getproperty         QName(PackageNamespace(""), "name_")
	pushstring			"Arena"
	ifeq				END
	
	getlex              QName(PackageNamespace(""), "map_")
	getproperty         QName(PackageNamespace(""), "name_")
	pushstring			"Vault" ; No more annoying nexusing from vault
	ifeq				END
	
	getlex				QName(PackageNamespace(""), $"charHp")
	getlex				QName(PackageNamespace(""), $"charMaxHp")
	convert_d
	divide
	pushdouble 			.25 ; It's 25% now
	ifgt				END
	getlex              QName(PackageNamespace(""), "map_")
	getproperty         QName(PackageNamespace(""), "gs_")
	getproperty         QName(PackageNamespace(""), "gsc_")
	callpropvoid        QName(PackageNamespace(""), $"funcEscape"), 0
END:
	pushtrue
As a side note I'll say now, if you want to have comment in the code, you can do that by using ; and writing your comment after that. Now we just need to add the code to the client. Make a new line after 4932 and insert the modified auto-nexus code there. It should look like this:
Code:
L589:
      getlex              QName(PackageNamespace("", "#0"), "_-1RH")
      getlocal1
      setproperty         QName(PackageNamespace("", "#0"), "lastDamage_")

L592:
      pushtrue
L593:
; _-names
#set charHp "_-1nm"
#set charMaxHp "_-0J6"
#set funcEscape "escape"

; code
	pop
	getlocal0
	getlex              QName(PackageNamespace(""), "map_")
	getproperty         QName(PackageNamespace(""), "player_")
	ifne				END
	
	getlex              QName(PackageNamespace(""), "map_")
	getproperty         QName(PackageNamespace(""), "name_")
	pushstring			"Nexus"
	ifeq				END
	
	getlex              QName(PackageNamespace(""), "map_")
	getproperty         QName(PackageNamespace(""), "name_")
	pushstring			"Arena"
	ifeq				END
	
	getlex              QName(PackageNamespace(""), "map_")
	getproperty         QName(PackageNamespace(""), "name_")
	pushstring			"Vault" ; No more annoying nexusing from vault
	ifeq				END
	
	getlex				QName(PackageNamespace(""), $"charHp")
	getlex				QName(PackageNamespace(""), $"charMaxHp")
	convert_d
	divide
	pushdouble 			.25 ; It's 25% now
	ifgt				END
	getlex              QName(PackageNamespace(""), "map_")
	getproperty         QName(PackageNamespace(""), "gs_")
	getproperty         QName(PackageNamespace(""), "gsc_")
	callpropvoid        QName(PackageNamespace(""), $"funcEscape"), 0
END:
	pushtrue
      returnvalue
     end ; code
    end ; body
   end ; method
  end ; trait
Now you're ready to recompile and test if it works.
awesome!

tyvm
Thanks for making this.
Lucifer gave me a link to a nice page that contains a huge list of opcodes, what they do, and how you use them.
AVM2 Instructions
Pretty useful for any beginner OR advanced user.
great tutorial, I myself have only an hour or two of coding knowledge and i was able to follow your guide thanks and good job.

well mostly my swf wont open...


ok so i have the right file open in the attached area? i'm not sure but im pretty sure i placed the code wrong?

idk how to remove the 1 attachment the idk.jpg.
idk.jpg169 KB · 60 downloads
Quote Originally Posted by 11770 View Post
great tutorial, I myself have only an hour or two of coding knowledge and i was able to follow your guide thanks and good job.

well mostly my swf wont open...


ok so i have the right file open in the attached area? i'm not sure but im pretty sure i placed the code wrong?

idk how to remove the 1 attachment the idk.jpg.
It should look like:
Code:
L67:
     pop
     pushtrue
     returnvalue
I guess you opened "prod.txt" with regular notepad instead of using Notepad++. Regular notepad sometimes doesn't show the code correctly so you shouldn't use it.
thanks for the help, yea i kinda noticed that when i opened the .xml file with notepad by mistake.. it was all messed up. so i used Dreamweaver instead.

Quote Originally Posted by CrazyJani View Post
The newer _-name for _-1Wb.class.asasm is _-1oC.class.asasm!

Now scroll to line number 498 in _-1Wb.class.asasm because the 19.0.0_prod.xml had that line marked down there. Then scroll in the _-0oC.class.asasm to about same lines of code and search for matches on surrounding code. You'll notice that line number 489 in _-0oC.class.asasm matches with the line number 498 in _-Wb.class.asasm. Check it for yourself they look really similar based on the surroundings.

The newer line number for 498 (_-1Wb.class.asasm) is 489 (_-1oC.class.asasm)!

Now you can edit the_-0oC.class.asasm by inserting a new row after line number 489 and copying the code from prod.txt which locates in same folder with 19.0.0_prod.xml. Insert the copied code on the new line you created (490).
now about the above when u mention _-0oC.class.asasm i opened this file in my search box but its in client 190's folder is that the 1 im supposed to edit or and i supposed to edit _-1oC.class.asasm?
Quote Originally Posted by 11770 View Post
thanks for the help, yea i kinda noticed that when i opened the .xml file with notepad by mistake.. it was all messed up. so i used Dreamweaver instead.



now about the above when u mention _-0oC.class.asasm i opened this file in my search box but its in client 190's folder is that the 1 im supposed to edit or and i supposed to edit _-1oC.class.asasm?
That was a typo, sorry for confusing you.
im confused either way, like i said i only have 1-2 hours of coding exp. also i lined up my coding and it still doesn't even open let alone give me an error code :/
If you want to see what is throwing your error download the debug version of flash projector (same download location).

It will show a popup with the class with the error or if you causes a stack error
lol i'm getting like 50 errors, maybe i shouldn't be attempting this :/
When I try to run the .bat file it says ''The program or feature "\??\C:\RABCDAsm\swfdecompress.exe" cannot start or run due to incompatibility with 64-bit versions of Windows. Please contact the software vendor to ask it a 64-bit Windows compatible version is available."

I'm running windows 8 x64

Can I get some guidance on this?
plz dont take over my swf edit tut
Quote Originally Posted by 6david7 View Post
plz dont take over my swf edit tut
Firstly, your tutorial was directly copy-pasted from elit****ers. Secondly it only taught how to decompile and recompile the client
Wow, I've never seen this tutorial before now. I learned how to update it the same way, without any experience or help. Just basic knowledge. I don't think I'd be able to do the last step with modifying the code though, just updating what's already made.

Thanks for the help, helped out with a few things I had a problem with though.

Little help with changing it though:

Try not taking lines like

getlocal3

^ those change quite often, and I honestly doubt you'll be able to find a file type with less than 50 getlocal3 or so xD

or

trait slot QName(PrivateNamespace("*", "com.company.assembleegameclient.game:_-03C"), "_-gv")

See how it has the _-Name ?
Yeah, if you attempt to search that in the new update (assuming you're updating it)
Then you won't be able to find it, since the _-Name is no longer the same.

However, taking a line like
QName(PackageNamespace("flash.display"), "LoaderInfo")
Which isn't found often, helps a lot.

Using AstroGrep is honestly the most helpful thing ever. Even with Notepad++ file search, I think AstroGrep is much better.

Just realized that's the same example as the one in connecting to production
Posts 1–15 of 25 · Page 1 of 2

Post a Reply

Similar Threads

Tags for this Thread

None

Talk with us