Disabling lagromancer effect in client

Posts 16 of 6 · Page 1 of 1
Disabling lagromancer effect in client
I got many questions whether it's possible to disable the necromancer healing effect in the client and if so, how, so I'm going to make a little tutorial.

First of all, I'd like to state here that I don't support this kind of modifications of the client, since it has to be updated after every new release and writing a proxy is much more profitable on the long run. (Disabling the lagromance effect takes 2 lines of code and never needs to be updated!)

I'm assuming here you are already familiar with rabcdasm, and you can search in files. Always use case sensitive seaching mode unless I state otherwise.
I use 13.2 client (1367279130), but it can be done with any version of clients (the names will differ though).

The effect is triggered by the SHOW_EFFECT packet, it is sent by the server to the client, so if someone uses the necro ability the server will tell your client that it should show the effect. There are limited number of effects, I used my proxy to find out which one it is but you can try blocking other effect too if you want to test it. (the earthquake is an effect too)
The necro effect is the effect number 9, called FlowEffect.

Find the class definition of the SHOW_EFFECT packet. I use the grep commandline tool for searching, you can use whatever you want:
Code:
$ grep -r SHOW_EFFECT
_-0a/_-SZ.class.asasm:      pushstring          "SHOW_EFFECT"
Open _-0a/_-SZ.class.asasm, go to the end of the file you will see something like this:
Code:
 trait const QName(PackageNamespace("", "#0"), "_-19G") slotid 1 type QName(PackageNamespace("", "#0"), "int") value Integer(0) end
 trait const QName(PackageNamespace("", "#0"), "_-0EH") slotid 2 type QName(PackageNamespace("", "#0"), "int") value Integer(1) end
 trait const QName(PackageNamespace("", "#0"), "_-1CI") slotid 3 type QName(PackageNamespace("", "#0"), "int") value Integer(2) end
 trait const QName(PackageNamespace("", "#0"), "_-12Z") slotid 4 type QName(PackageNamespace("", "#0"), "int") value Integer(3) end
 trait const QName(PackageNamespace("", "#0"), "_-1I-") slotid 5 type QName(PackageNamespace("", "#0"), "int") value Integer(4) end
 trait const QName(PackageNamespace("", "#0"), "_-0Z6") slotid 6 type QName(PackageNamespace("", "#0"), "int") value Integer(5) end
 trait const QName(PackageNamespace("", "#0"), "_-09H") slotid 7 type QName(PackageNamespace("", "#0"), "int") value Integer(6) end
 trait const QName(PackageNamespace("", "#0"), "_-0FT") slotid 8 type QName(PackageNamespace("", "#0"), "int") value Integer(7) end
 trait const QName(PackageNamespace("", "#0"), "_-0E8") slotid 9 type QName(PackageNamespace("", "#0"), "int") value Integer(8) end
 trait const QName(PackageNamespace("", "#0"), "_-KK") slotid 10 type QName(PackageNamespace("", "#0"), "int") value Integer(9) end
 trait const QName(PackageNamespace("", "#0"), "_-10L") slotid 11 type QName(PackageNamespace("", "#0"), "int") value Integer(10) end
 trait const QName(PackageNamespace("", "#0"), "_-ME") slotid 12 type QName(PackageNamespace("", "#0"), "int") value Integer(11) end
 trait const QName(PackageNamespace("", "#0"), "_-IO") slotid 13 type QName(PackageNamespace("", "#0"), "int") value Integer(12) end
 trait const QName(PackageNamespace("", "#0"), "_-or") slotid 14 type QName(PackageNamespace("", "#0"), "int") value Integer(13) end
 trait const QName(PackageNamespace("", "#0"), "_-1Sd") slotid 15 type QName(PackageNamespace("", "#0"), "int") value Integer(14) end
 trait const QName(PackageNamespace("", "#0"), "_-1as") slotid 16 type QName(PackageNamespace("", "#0"), "int") value Integer(15) end
 trait const QName(PackageNamespace("", "#0"), "_-1ZR") slotid 17 type QName(PackageNamespace("", "#0"), "int") value Integer(16) end
We need the one with the value of 9. That's the _-KK.
Find which file it is used in:
Code:
_-16i/_-AK.class.asasm:      getproperty         QName(PackageNamespace("", "#0"), "_-KK")
_-0a/_-SZ.class.asasm:    findproperty        QName(PackageNamespace("", "#0"), "_-KK")
_-0a/_-SZ.class.asasm:    initproperty        QName(PackageNamespace("", "#0"), "_-KK")
_-0a/_-SZ.class.asasm: trait const QName(PackageNamespace("", "#0"), "_-KK") slotid 10 type QName(PackageNamespace("", "#0"), "int") value Integer(9) end
They are the _-16i/_-AK.class.asasm and the _-0a/_-SZ.class.asasm (this one) files.
Open _-16i/_-AK.class.asasm and look for the _-KK in it:
Code:
L718:
      getlex              QName(PackageNamespace("_-0a"), "_-SZ")
      getproperty         QName(PackageNamespace("", "#0"), "_-KK")
      getlocal            7
      iffalse             L797

      getlocal            6
      getlocal            8
      iftrue              L738

L725:
      ifstrictne          L728

L726:
      pushbyte            8
      jump                L849
The code is a bit obfuscated here it is after cleaning up the code a little bit:
Code:
L718:
      getlex              QName(PackageNamespace("_-0a"), "_-SZ")
      getproperty         QName(PackageNamespace("", "#0"), "_-KK")

      getlocal            6
      ifstrictne          L728

      pushbyte            8
      jump                L849
L728:
It's part of a switch-case if you are familiar with other languages, you may know what it is. If local6 is not equal to _-0a._-SZ._-KK (9), jump to the next case (effect), if it is, then push 8 onto the top of the stack and jump to the swich table:
Code:
      lookupswitch        L582, [L27, L67, L79, L102, L154, L188, L224, L264, L306, L346, L390, L433, L470, L508, L513, L549, L582]

L851:
      returnvoid
L582 is the default value (if the effect is not found), but now we need the 8th label (remember the pushbyte 8 before the jump). Start the count with zero.
Code:
L306:
      label
      getlocal2
      getproperty         QName(PackageNamespace("", "#0"), "goDict_")
      getlocal1
      getproperty         QName(PackageNamespace("", "#0"), "targetObjectId_")
      getproperty         MultinameL([PrivateNamespace("*", "_-16i:_-AK"), PackageNamespace("", "#0"), PackageNamespace("_-16i"), PackageNamespace("_-065"), PackageNamespace("_-0a"), PackageNamespace("com.company.assembleegameclient.objects"), PrivateNamespace("*", "_-16i:_-AK/instance"), PackageInternalNs("_-16i"), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("_-pR"), PackageNamespace("_-1-D"), ProtectedNamespace("_-2W"), StaticProtectedNs("_-2W"), StaticProtectedNs("_-0uN")])
      coerce              QName(PackageNamespace("com.company.assembleegameclient.objects"), "GameObject")
      setlocal3

      getlocal            7
      iffalse             L319

      getlocal3
      pushnull
      ifne                L320

L319:
      jump                L851

L320:
      findpropstrict      QName(PackageNamespace("_-pR"), "FlowEffect")
      getlocal1
      getproperty         QName(PackageNamespace("", "#0"), "pos1_")
      getlocal3
      getlocal1
      getproperty         QName(PackageNamespace("", "#0"), "color_")
      constructprop       QName(PackageNamespace("_-pR"), "FlowEffect"), 3
      coerce              QName(PackageNamespace("_-pR"), "_-1ZD")
      setlocal            4

      getlocal            7
      dup
      iftrue              L335

      pop
      getlocal0
      convert_b
L335:
      iffalse             L345

      getlocal2
      getlocal            4
      getlocal1
      getproperty         QName(PackageNamespace("", "#0"), "pos1_")
      getproperty         QName(PackageNamespace("", "#0"), "x_")
      getlocal1
      getproperty         QName(PackageNamespace("", "#0"), "pos1_")
      getproperty         QName(PackageNamespace("", "#0"), "y_")
      callpropvoid        QName(PackageNamespace("", "#0"), "addObj"), 3

L345:
      jump                L851

L346:
After cleaning the code up a little bit:
Code:
L306:
      label
      getlocal2
      getproperty         QName(PackageNamespace("", "#0"), "goDict_")
      getlocal1
      getproperty         QName(PackageNamespace("", "#0"), "targetObjectId_")
      getproperty         MultinameL([PrivateNamespace("*", "_-16i:_-AK"), PackageNamespace("", "#0"), PackageNamespace("_-16i"), PackageNamespace("_-065"), PackageNamespace("_-0a"), PackageNamespace("com.company.assembleegameclient.objects"), PrivateNamespace("*", "_-16i:_-AK/instance"), PackageInternalNs("_-16i"), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("_-pR"), PackageNamespace("_-1-D"), ProtectedNamespace("_-2W"), StaticProtectedNs("_-2W"), StaticProtectedNs("_-0uN")])
      coerce              QName(PackageNamespace("com.company.assembleegameclient.objects"), "GameObject")
      setlocal3

      getlocal3
      pushnull
      ifne                L320

      jump                L851

L320:
      findpropstrict      QName(PackageNamespace("_-pR"), "FlowEffect")
      getlocal1
      getproperty         QName(PackageNamespace("", "#0"), "pos1_")
      getlocal3
      getlocal1
      getproperty         QName(PackageNamespace("", "#0"), "color_")
      constructprop       QName(PackageNamespace("_-pR"), "FlowEffect"), 3
      coerce              QName(PackageNamespace("_-pR"), "_-1ZD")
      setlocal            4

      getlocal2
      getlocal            4
      getlocal1
      getproperty         QName(PackageNamespace("", "#0"), "pos1_")
      getproperty         QName(PackageNamespace("", "#0"), "x_")
      getlocal1
      getproperty         QName(PackageNamespace("", "#0"), "pos1_")
      getproperty         QName(PackageNamespace("", "#0"), "y_")
      callpropvoid        QName(PackageNamespace("", "#0"), "addObj"), 3

      jump                L851
This code calls the FlowEffect that we want to prevent. We can put a
Code:
      jump                L851
right after the label, but we already know that L851 is just a label to returnvoid so we can directly put there a returnvoid:
Code:
L306:
      label
      returnvoid
That's it.
Note: In every method the obfuscator uses 2 locals to confuse you, you can check the code between the "code" tag and "getlocal0, pushscope", instructions, usually one of it will be false and the other true, so you will know what you should and should not ignore. In the method above, it's
Code:
     code
      pushfalse ;stack:false
      pushtrue ;stack:true,false
      setlocal            7 ;local7 is set by the obfuscator to true -> stack:false

      jump                L10 ; jumps to L10

      lessthan ;dead code
      declocal            6 ;dead code
      kill                7 ;dead code
      inclocal            3 ;dead code
      getlocal            7 ;dead code
      declocal            5 ;dead code
L10:
      setlocal            8 ;puts false into local8 -> stack:empty

      getlocal0 ;here starts the "real" code
      pushscope
so local7 and local8 are only there to confuse you with the values of true and false respectively.

tl;dr: Look for FlowEffect in the class of map_.gs_.gsc_, find the "label" instruction somewhere above it and put "returnvoid" right after the "label".
(I haven't tested it yet but it should work -_-)
I'm a little surprised you didn't test the one line insert. I'm guessing you updated the hack when you decided to write this tutorial? In any case, good post. Tutorials are always nice.
Quote Originally Posted by nilly View Post
I'm a little surprised you didn't test the one line insert. I'm guessing you updated the hack when you decided to write this tutorial? In any case, good post. Tutorials are always nice.
No, I don't use modified clients and I don't play anymore, but I have a proxy I like developing little by little by little and it block that effect, so if block the same effect in the client there is no reason not to work. That 1 liner does it and the _-16i/_-AK processes all the network traffic and I checked what it does when it recieves a SHOW_EFFECT: immediately enters a switch case, to decide wich effectType was recieved and to process it based on that. If I block everything in the case of the _-KK, I cannot imagine what could go wrong, but I will test it later.
There is a threard about a hack used for wizzy abilities so it hits all 20 shots on.
I wonder if any of u two coders can do that
Thx for your time
-75dragon
Quote Originally Posted by 75dragon View Post
There is a threard about a hack used for wizzy abilities so it hits all 20 shots on.
I wonder if any of u two coders can do that
Thx for your time
-75dragon
I've already done it. How about you do it?
Posts 16 of 6 · Page 1 of 1

Post a Reply

Similar Threads

Tags for this Thread

None

Need help?