• Unfortunately, we have experienced significant hard drive damage that requires urgent maintenance and rebuilding. The forum will be a state of read only until we install our new drives and rebuild all the configurations needed. Please follow our Facebook page for updates, we will be back up shortly! (The forum could go offline at any given time due to the nature of the failed drives whilst awaiting the upgrades.) When you see an Incapsula error, you know we are in the process of migration.

[Release] Unpacked main season11

Junior Spellweaver
Joined
Feb 11, 2014
Messages
142
Reaction score
34
Well, this is just latest main. You will need to adapt server files, but client side is ready :)

I am into general reverse engineering, not MU specific, the official server executables in general are always a lot of fun to unpack and analyze


Fun? It is not fun when you've already tried 10000000 Times.I am not Reverse Eng. andI've never worked with NOOBYPROTECT or so... Would you please give me some help i want to Open this Gameserver.exe.
It is 1.01.10B_2 version.
need it RUNNING even with ERROR.

 
Hybrid
Loyal Member
Joined
Mar 15, 2006
Messages
451
Reaction score
285
Has anyone already reversed the EncodePacketByHeadcode(), that function called before the EncryptC3Packet()? I'm working on it, but it needs a better approach than mine because it will take an eternity for me to translate all the subfunctions it uses for every MU packet. I'm sure that a more experienced reverser will be able to figure out a better way to accomplish it, because the subfunctions are not hard to translate into C language.

If it uses virtual table to call those functions, you can easy replace it with your own with empty functions, so it doesn't encode it at all.
 
Newbie Spellweaver
Joined
Jul 31, 2015
Messages
39
Reaction score
33
If it uses virtual table to call those functions, you can easy replace it with your own with empty functions, so it doesn't encode it at all.

Was about to write same thing, just nop the encoding call lol
 
Newbie Spellweaver
Joined
Sep 19, 2011
Messages
11
Reaction score
1
If it uses virtual table to call those functions, you can easy replace it with your own with empty functions, so it doesn't encode it at all.
I want to write the encode function, not to remove it.
 
Newbie Spellweaver
Joined
Jul 31, 2015
Messages
39
Reaction score
33
I want to write the encode function, not to remove it.

What for do you take the harder, less stable road? Imagine that new version of main comes - the original packets are the same, but twisting functions are different. With encrpytion removing approach u will have system handling every packet correctly, without obligation of decrypting twisters fo every packet every version over and over
 
Kingdom of Shadows
Loyal Member
Joined
Jul 13, 2007
Messages
923
Reaction score
320
I want to write the encode function, not to remove it.
There is season 9 gs released (ex901 test I think it's called here on forum) compiled as debug .exe and you may reverse from it. There are 82 pairs of functions twisting & correcting the packets.
 
Newbie Spellweaver
Joined
Jul 31, 2015
Messages
39
Reaction score
33
I am not around mu, I wonder, do you use emulators written from scratch or official leaked compiled server files? In first case, just dump the twister on client side. In second - thats hard
 
Newbie Spellweaver
Joined
Jul 31, 2015
Messages
39
Reaction score
33
Noise around what? Id rather say lots of clueless people hopping around here.

I actually took a deeper look into the twister thingy. Every function is obfuscated on client side, i managed to deobfuscate it. Basically it is poop ton of byte shifts, xors, masking etc
 
Newbie Spellweaver
Joined
Nov 24, 2008
Messages
34
Reaction score
71
I'll gib u $666WCoin for dupe mu online ex11.

You should reverse twister algorithms generation and then guess seed used to generate twisters for current main version.
 
Newbie Spellweaver
Joined
Sep 19, 2011
Messages
11
Reaction score
1
Noise around what? Id rather say lots of clueless people hopping around here.

I actually took a deeper look into the twister thingy. Every function is obfuscated on client side, i managed to deobfuscate it. Basically it is poop ton of byte shifts, xors, masking etc

Even obfuscated the twister functions are very easy to understand and to translate into C. I have translated 5 until now, only by hands^_^. But I think there may exist a better approach. Using a dump, as you suggested, is a good idea. I will try to work with it.

mirraseq: your suggestion is the pro solution, but it can only be done by pro crax0rz, not by me. xD
 
NN - Nord & Noob
Loyal Member
Joined
Jul 15, 2004
Messages
1,207
Reaction score
689
I used to reversed 1 or 2.. but then i got bored of that 100lines crap code
a[4] := a[3]
a[5] := a[4] xor a[5]
a[6] := a[7] shl 1
untill 100line code.

http://forum.ragezone.com/f508/reversing-ex700-ex700plus-protocol-crypt-888277/

i even reversed DES T__T cuz im noob and idiot :F my IQ test gives errors and ask me try again in next life

Twister sht
Code:
procedure DecryptLevel2(lpSource: Pointer);
var
 Offset: Byte;
 ContentSize: Word;
 PBuffer: PByte;
 Condition, Condition2: Byte;
begin
 Offset := GetHdrSize(lpSource) +2; // Counter = 2
 ContentSize := GetContentSize(lpSource);
 PBuffer := PByte(lpSource) + Offset;

 if not (ContentSize >= 4) then
  Exit // No Decryption for this size
 else
 if not (ContentSize >= 8) then
  begin
   PByte(PBuffer +3)^ := PByte(PBuffer +3)^ xor $85; //09CB6897

   Condition   := SAR(PByte(PBuffer +3)^, 4) and 1;
   Condition2  := SAR(PByte(PBuffer +3)^, 2) and 1;

   if (Condition = 0) then
    PByte(PBuffer +3)^ := PByte(PBuffer +3)^ and $EF //09BFCD94
   else
    PByte(PBuffer +3)^ := PByte(PBuffer +3)^ or $10; //09CB6573

   if (Condition2 = 0) then
    PByte(PBuffer +3)^ := PByte(PBuffer +3)^ and $EF //09BFCD94
   else
    PByte(PBuffer +3)^ := PByte(PBuffer +3)^ or $10; //09CB6573

   Condition   := SAR(PByte(PBuffer +7)^, 4) and 1;
   Condition2  := SAR(PByte(PBuffer +7)^, 5) and 1;

   if (Condition = 0) then
    PByte(PBuffer +7)^ := PByte(PBuffer +7)^ and $DF //09BFCCF4
   else
    PByte(PBuffer +7)^ := PByte(PBuffer +7)^ or $20; //09CB6356


   if (Condition2 = 0) then
    PByte(PBuffer +7)^ := PByte(PBuffer +7)^ and $EF //09BFCD36
   else
    PByte(PBuffer +7)^ := PByte(PBuffer +7)^ or $10;
  end
 else
 if not (ContentSize >= 16) then
  begin
   PByte(PBuffer +3)^ := PByte(PBuffer +3)^ xor $85; //09CB6897

   Condition   := SAR(PByte(PBuffer +3)^, 4) and 1;
   Condition2  := SAR(PByte(PBuffer +3)^, 2) and 1;

   if (Condition = 0) then
    PByte(PBuffer +3)^ := PByte(PBuffer +3)^ and $EF //09BFCD94
   else
    PByte(PBuffer +3)^ := PByte(PBuffer +3)^ or $10; //09CB6573

   if (Condition2 = 0) then
    PByte(PBuffer +3)^ := PByte(PBuffer +3)^ and $EF //09BFCD94
   else
    PByte(PBuffer +3)^ := PByte(PBuffer +3)^ or $10; //09CB6573

   Condition   := SAR(PByte(PBuffer +7)^, 4) and 1;
   Condition2  := SAR(PByte(PBuffer +7)^, 5) and 1;

   if (Condition = 0) then
    PByte(PBuffer +7)^ := PByte(PBuffer +7)^ and $DF //09BFCCF4
   else
    PByte(PBuffer +7)^ := PByte(PBuffer +7)^ or $20; //09CB6356


   if (Condition2 = 0) then
    PByte(PBuffer +7)^ := PByte(PBuffer +7)^ and $EF //09BFCD36
   else
    PByte(PBuffer +7)^ := PByte(PBuffer +7)^ or $10;
  end
 else
 if not (ContentSize >= 32) then
  begin
   PByte(PBuffer +$1F)^ := PByte(PBuffer +$1F)^ xor $7D;

   Condition := PByte(PBuffer +$10)^;
   PByte(PBuffer +$10)^ := PByte(PBuffer +$18)^;
   PByte(PBuffer +$18)^ := Condition;


   Condition2 := (PByte(PBuffer +$1A)^ shr 5);
   PByte(PBuffer)^ := PByte(PBuffer +$1A)^ or Condition2;
   PByte(PBuffer +$1A)^ := (PByte(PBuffer)^ shl 3);

   Condition := PByte(PBuffer +3)^;
   PByte(PBuffer +3)^ := PByte(PBuffer +$18)^;
   PByte(PBuffer +$18)^ := Condition;

   Condition := (PByte(PBuffer +4)^ shl 2);
   PByte(PBuffer +4)^ := PByte(PBuffer +4)^ shr 6;
   PByte(PBuffer +4)^ := (PByte(PBuffer +4)^ or Condition);


   Condition  := (PByte(PBuffer +2)^ shr 5) and 1;
   Condition2 := (PByte(PBuffer +2)^ shr 2) and 1;

   if (Condition2 = 0) then
    PByte(PBuffer +2)^ := PByte(PBuffer +2)^ and $DF //09CB75DE
   else
    PByte(PBuffer +2)^ := PByte(PBuffer +2)^ or $20; //09CB75D0

   if (Condition = 0) then
    PByte(PBuffer +2)^ := PByte(PBuffer +2)^ and $FB //09BFD34A
   else
    PByte(PBuffer +2)^ := PByte(PBuffer +2)^ or 4;   //09CB75B7

   Condition  := (PByte(PBuffer +6)^ shr 7) and 1; //8bit
   Condition2 := (PByte(PBuffer +6)^ shr 6) and 1; //7bit

   if (Condition = 0) then
    PByte(PBuffer +6)^ := PByte(PBuffer +6)^ and $BF //09CB74CB
   else
    PByte(PBuffer +6)^ := PByte(PBuffer +6)^ or $40; //09CB74BD

   if (Condition2 = 0) then
    PByte(PBuffer +6)^ := PByte(PBuffer +6)^ and $7F //09CB755F
   else
    PByte(PBuffer +6)^ := PByte(PBuffer +6)^ or $80; //$FFFFFF7F

   PByte(PBuffer +$11)^ := PByte(PBuffer +$11)^ xor $AC;

   Condition  := (PByte(PBuffer +$15)^ shr 2) and 1;
   Condition2 := (PByte(PBuffer +$15)^ shr 2) and 1;

   if (Condition = 0) then
    PByte(PBuffer +$15)^ := PByte(PBuffer +$15)^ and $FB //9CB740B
   else
    PByte(PBuffer +$15)^ := PByte(PBuffer +$15)^ or 4;

   if (Condition2 = 0) then
    PByte(PBuffer +$15)^ := PByte(PBuffer +$15)^ and $DF
   else
    PByte(PBuffer +$15)^ := PByte(PBuffer +$15)^ or 4;

   PByte(PBuffer +1)^ := PByte(PBuffer +1)^ xor $1A;  //09CB7290
  end
 else
  begin
   Condition  := PByte(PBuffer +$C)^ shl 6;
   Condition2 := PByte(PBuffer +$C)^ shr 2;
   PByte(PBuffer +$C)^ := (Condition or Condition2);

   Condition  := PByte(PBuffer +$A)^ shr 1 and 1;
   Condition2 := PByte(PBuffer +$A)^ shr 1 and 1;

   if (Condition = 0) then
    PByte(PBuffer +$A)^ := PByte(PBuffer +$A)^ and $FD //09BFD1E6
   else
    PByte(PBuffer +$A)^ := PByte(PBuffer +$A)^ or $20;

   if (Condition2 = 0) then
    PByte(PBuffer +$A)^ := PByte(PBuffer +$A)^ and $FD //09BFD251
   else
    PByte(PBuffer +$A)^ := PByte(PBuffer +$A)^ or 2;   //09BFD242

   PByte(PBuffer +8)^ := PByte(PBuffer +8)^ xor $DF;
   PByte(PBuffer)^ := PByte(PBuffer)^ xor $A;

   Condition := PByte(PBuffer +$B)^;
   PByte(PBuffer +$B)^ := PByte(PBuffer +2)^;
   PByte(PBuffer +$B)^ := Condition;
  end;
end;

procedure EncryptLevel2(lpSource: Pointer);  //1.14.17
var
 Offset: Byte;
 ContentSize: Word;
 PBuffer: PByte;
 Condition, Condition2: Byte;
begin
 Offset := GetHdrSize(lpSource) +2; // Counter = 2
 ContentSize := GetContentSize(lpSource);
 PBuffer := PByte(lpSource) + Offset;

 if not (ContentSize >= 4) then
  Exit // No Encryption for this size
 else
 if not (ContentSize >= 8) then
  begin
   PByte(PBuffer +2)^ := ((PByte(PBuffer +2)^ shr 2) or (PByte(PBuffer +2)^ shl 6)) xor $91;
   PByte(PBuffer +3)^ := PByte(PBuffer +3)^ xor $F6; //09CB62E6
  end
 else
 if not (ContentSize >= 16) then //006681FB
  begin
   Condition   := SAR(PByte(PBuffer +7)^, 4) and 1;
   Condition2  := SAR(PByte(PBuffer +7)^, 5) and 1;

   if (Condition = 0) then
    PByte(PBuffer +7)^ := PByte(PBuffer +7)^ and $DF //09BFCCF4
   else
    PByte(PBuffer +7)^ := PByte(PBuffer +7)^ or $20; //09CB6356


   if (Condition2 = 0) then
    PByte(PBuffer +7)^ := PByte(PBuffer +7)^ and $EF //09BFCD36
   else
    PByte(PBuffer +7)^ := PByte(PBuffer +7)^ or $10;

   Condition   := SAR(PByte(PBuffer +3)^, 4) and 1;
   Condition2  := SAR(PByte(PBuffer +3)^, 2) and 1;

   if (Condition = 0) then
    PByte(PBuffer +3)^ := PByte(PBuffer +3)^ and $EF //09BFCD94
   else
    PByte(PBuffer +3)^ := PByte(PBuffer +3)^ or $10; //09CB6573

   if (Condition2 = 0) then
    PByte(PBuffer +3)^ := PByte(PBuffer +3)^ and $EF //09BFCD94
   else
    PByte(PBuffer +3)^ := PByte(PBuffer +3)^ or $10; //09CB6573

   PByte(PBuffer +3)^ := PByte(PBuffer +3)^ xor $85; //09CB6897
  end
 else
 if not (ContentSize >= 32) then // Login packet
  begin
   PBuffer := PByte(lpSource) + Offset;
   PByte(PBuffer +1)^ := PByte(PBuffer +1)^ xor $1A;  //09CB7290

   Condition  := SAR(PByte(PBuffer +$15)^, 2) and 1;
   Condition2 := SAR(PByte(PBuffer +$15)^, 2) and 1;

   if (Condition = 0) then
    PByte(PBuffer +$15)^ := PByte(PBuffer +$15)^ and $FB //9CB740B
   else
    PByte(PBuffer +$15)^ := PByte(PBuffer +$15)^ or 4;

   if (Condition2 = 0) then
    PByte(PBuffer +$15)^ := PByte(PBuffer +$15)^ and $DF
   else
    PByte(PBuffer +$15)^ := PByte(PBuffer +$15)^ or 4;

    Condition  := SAR(PByte(PBuffer +6)^, 7) and 1;
    Condition2 := SAR(PByte(PBuffer +6)^, 6) and 1;

   if (Condition = 0) then
    PByte(PBuffer +6)^ := PByte(PBuffer +6)^ and $BF //09CB74CB
   else
    PByte(PBuffer +6)^ := PByte(PBuffer +6)^ or $40; //09CB74BD

   if (Condition2 = 0) then
    PByte(PBuffer +6)^ := PByte(PBuffer +6)^ and $7F //09CB755F
   else
    PByte(PBuffer +6)^ := PByte(PBuffer +6)^ or $80; //$FFFFFF7F

   PByte(PBuffer +$11)^ := PByte(PBuffer +$11)^ xor $AC;

   Condition  := SAR(PByte(PBuffer +2)^, 5) and 1;
   Condition2 := SAR(PByte(PBuffer +2)^, 2) and 1;

   if (Condition = 0) then
    PByte(PBuffer +2)^ := PByte(PBuffer +2)^ and $FB //09BFD34A
   else
    PByte(PBuffer +2)^ := PByte(PBuffer +2)^ or 4;   //09CB75B7

   if (Condition2 = 0) then
    PByte(PBuffer +2)^ := PByte(PBuffer +2)^ and $DF //09CB75DE
   else
    PByte(PBuffer +2)^ := PByte(PBuffer +2)^ or $20; //09CB75D0


   Condition := SAR(PByte(PBuffer +4)^, 2);
   PByte(PBuffer +4)^ := PByte(PBuffer +4)^ shl 6;
   PByte(PBuffer +4)^ := (PByte(PBuffer +4)^ or Condition);

   Condition := PByte(PBuffer +$18)^;
   PByte(PBuffer +$18)^ := PByte(PBuffer +3)^;
   PByte(PBuffer +3)^   := Condition;

   Condition  := SAR(PByte(PBuffer +$1A)^, 3); //09CB7680
   Condition2 := (PByte(PBuffer +$1A)^ shl 5);
   PByte(PBuffer)^ := (Condition or Condition2);
   PByte(PBuffer +$1A)^ := Condition;

   Condition := PByte(PBuffer +$10)^;
   PByte(PBuffer +$10)^ := PByte(PBuffer +$18)^;
   PByte(PBuffer +$18)^ := Condition;

   PByte(PBuffer +$1F)^ := PByte(PBuffer +$1F)^ xor $7D;
  end
 else
  begin
   Condition := PByte(PBuffer +2)^;
   PByte(PBuffer +2)^ := PByte(PBuffer +$B)^;
   PByte(PBuffer +$B)^ := Condition;

   PByte(PBuffer +8)^ := PByte(PBuffer +8)^ xor $DF;
   PByte(PBuffer)^ := PByte(PBuffer)^ xor $A;

   Condition  := SAR(PByte(PBuffer +$A)^, 1) and 1;
   Condition2 := SAR(PByte(PBuffer +$A)^, 5) and 1;

   if (Condition = 0) then
    PByte(PBuffer +$A)^ := PByte(PBuffer +$A)^ and $FD //09BFD1E6
   else
    PByte(PBuffer +$A)^ := PByte(PBuffer +$A)^ or $20;

   if (Condition2 = 0) then
    PByte(PBuffer +$A)^ := PByte(PBuffer +$A)^ and $FD //09BFD251
   else
    PByte(PBuffer +$A)^ := PByte(PBuffer +$A)^ or 2;   //09BFD242

   Condition  := SAR(PByte(PBuffer +$C)^, 6);
   Condition2 := PByte(PBuffer +$C)^ shl 2;
   PByte(PBuffer +$C)^ := (Condition or Condition2);
  end;
end;

long time ago.. ahauhauahu
PS. i would reverse all, but then i noticed packettwister changes with every main.exe update and i give up
 
Last edited:
Newbie Spellweaver
Joined
Jul 31, 2015
Messages
39
Reaction score
33
Why are you even tryin to reverse the twisters, masohists?
 
Back
Top