|
You last visited: Today at 06:34
Advertisement
What is the importance of the SetKeys method?
Discussion on What is the importance of the SetKeys method? within the CO2 Private Server forum part of the Conquer Online 2 category.
07/10/2009, 01:57
|
#1
|
elite*gold: 0
Join Date: Jul 2009
Posts: 5
Received Thanks: 1
|
What is the importance of the SetKeys method?
Could someone please tell me, if it is used regularly or rarely, and what the situation is?
Also, could someone please assist me in understanding this code, as it is difficult to follow:
Code:
public unsafe void SetKeys(uint inKey1, uint inKey2)
{
byte[] CS$0$0000;
uint dwKey1 = ((inKey1 + inKey2) ^ 0x4321) ^ inKey1;
uint dwKey2 = dwKey1 * dwKey1;
this.Key3 = new byte[0x100];
this.Key4 = new byte[0x100];
if (((CS$0$0000 = ConquerKeys.Key1) != null) && (CS$0$0000.Length != 0))
{
goto Label_0045;
}
fixed (void* uKey1 = null)
{
byte[] CS$0$0001;
goto Label_004E;
Label_0045:
uKey1 = CS$0$0000;
Label_004E:
if (((CS$0$0001 = this.Key3) != null) && (CS$0$0001.Length != 0))
{
goto Label_0064;
}
fixed (void* uKey3 = null)
{
byte[] CS$0$0002;
byte[] CS$0$0003;
goto Label_006D;
Label_0064:
uKey3 = CS$0$0001;
Label_006D:
if (((CS$0$0002 = ConquerKeys.Key2) == null) || (CS$0$0002.Length == 0))
{
fixed (void* uKey2 = null)
{
}
}
if (((CS$0$0003 = this.Key4) == null) || (CS$0$0003.Length == 0))
{
uKey4 = null;
}
else
{
uKey4 = CS$0$0003;
}
for (byte i = 0; i < 0x40; i = (byte) (i + 1))
{
uKey3[i * 4] = dwKey1 ^ uKey1[i * 4];
uKey4[i * 4] = dwKey2 ^ uKey2[i * 4];
}
}
}
uKey2 = null;
fixed (void* uKey4 = null)
{
this.OutCounter = 0;
this.UsingAlternate = true;
}
}
From what I believe, since no elements in Key3 and Key4 are being set directly, uKey3 and uKey4 are pointers to Key3 and Key4, and besides checking to see if Key1, Key2...4 are not null and their length is greater than 0, the main manipulation happens within the for loop.
So, given if you knew everything was valid, and you did not give that kind of access to Key1 or Key2, would this be the same as the above?
Code:
public unsafe void SetKeys(uint inKey1, uint inKey2)
{
uint dwKey1 = ((inKey1 + inKey2) ^ 0x4321) ^ inKey1;
uint dwKey2 = dwKey1 * dwKey1;
this.Key3 = new byte[0x100];
this.Key4 = new byte[0x100];
for (byte i = 0; i < 0x40; i = (byte) (i + 1))
{
this.Key3[i * 4] = dwKey1 ^ uKey1[i * 4];
this.Key4[i * 4] = dwKey2 ^ uKey2[i * 4];
}
this.OutCounter = 0;
this.UsingAlternate = true;
}
I'm getting lost in the if statements. It's given that Key3 and Key4 have been declared with a length of 256, and it would be terrible if Key1 and Key2 ever became null or lost their values, so why give it the ability, and why are the if statements important/what exactly are they doing?
Could someone please clear this up for me?
|
|
|
07/10/2009, 02:00
|
#2
|
elite*gold: 20
Join Date: Jan 2006
Posts: 890
Received Thanks: 241
|
Quote:
Originally Posted by pipe80
Could someone please tell me, if it is used regularly or rarely, and what the situation is?
Also, could someone please assist me in understanding this code, as it is difficult to follow:
Code:
public unsafe void SetKeys(uint inKey1, uint inKey2)
{
byte[] CS$0$0000;
uint dwKey1 = ((inKey1 + inKey2) ^ 0x4321) ^ inKey1;
uint dwKey2 = dwKey1 * dwKey1;
this.Key3 = new byte[0x100];
this.Key4 = new byte[0x100];
if (((CS$0$0000 = ConquerKeys.Key1) != null) && (CS$0$0000.Length != 0))
{
goto Label_0045;
}
fixed (void* uKey1 = null)
{
byte[] CS$0$0001;
goto Label_004E;
Label_0045:
uKey1 = CS$0$0000;
Label_004E:
if (((CS$0$0001 = this.Key3) != null) && (CS$0$0001.Length != 0))
{
goto Label_0064;
}
fixed (void* uKey3 = null)
{
byte[] CS$0$0002;
byte[] CS$0$0003;
goto Label_006D;
Label_0064:
uKey3 = CS$0$0001;
Label_006D:
if (((CS$0$0002 = ConquerKeys.Key2) == null) || (CS$0$0002.Length == 0))
{
fixed (void* uKey2 = null)
{
}
}
if (((CS$0$0003 = this.Key4) == null) || (CS$0$0003.Length == 0))
{
uKey4 = null;
}
else
{
uKey4 = CS$0$0003;
}
for (byte i = 0; i < 0x40; i = (byte) (i + 1))
{
uKey3[i * 4] = dwKey1 ^ uKey1[i * 4];
uKey4[i * 4] = dwKey2 ^ uKey2[i * 4];
}
}
}
uKey2 = null;
fixed (void* uKey4 = null)
{
this.OutCounter = 0;
this.UsingAlternate = true;
}
}
From what I believe, since no elements in Key3 and Key4 are being set directly, uKey3 and uKey4 are pointers to Key3 and Key4, and besides checking to see if Key1, Key2...4 are not null and their length is greater than 0, the main manipulation happens within the for loop.
So, given if you knew everything was valid, and you did not give that kind of access to Key1 or Key2, would this be the same as the above?
Code:
public unsafe void SetKeys(uint inKey1, uint inKey2)
{
uint dwKey1 = ((inKey1 + inKey2) ^ 0x4321) ^ inKey1;
uint dwKey2 = dwKey1 * dwKey1;
this.Key3 = new byte[0x100];
this.Key4 = new byte[0x100];
for (byte i = 0; i < 0x40; i = (byte) (i + 1))
{
this.Key3[i * 4] = dwKey1 ^ uKey1[i * 4];
this.Key4[i * 4] = dwKey2 ^ uKey2[i * 4];
}
this.OutCounter = 0;
this.UsingAlternate = true;
}
I'm getting lost in the if statements. It's given that Key3 and Key4 have been declared with a length of 256, and it would be terrible if Key1 and Key2 ever became null or lost their values, so why give it the ability, and why are the if statements important/what exactly are they doing?
Could someone please clear this up for me?
|
alltho im not going into detail, setkeys used for the encryption, without it you simply wont be able to login
btw, you really shouldnt decompile others coding, lol
|
|
|
07/10/2009, 05:01
|
#3
|
elite*gold: 0
Join Date: Jul 2009
Posts: 5
Received Thanks: 1
|
Quote:
Originally Posted by lostsolder05
alltho im not going into detail, setkeys used for the encryption, without it you simply wont be able to login
btw, you really shouldnt decompile others coding, lol
|
I may have missed something, but I have searched what I believe, was every file of 2 sources, and the only reference to SetKeys that I could find were the actual methods themselves.
I believe the reason you're not going into detail is because you truly don't know yourself.
By the way, you really should read more carefully.
Quote:
|
Originally Posted by InfamousNoone
SocketNetwork.dll pretty much handles the socket-system and encryptions for you it is not packed or obfuscated if you would like to decompile it and take a look at it, be my guest.
|
One of the reasons I decompiled SocketNetwork.dll was because there are so many resources that can tell you how to implement NPCs, mobs, and items, but there isn't much about how the encryption works, or what exactly makes up a packet, the process of packets for logging in/playing, or even how those packets are found, so it seems that we're leaving that up to those who have always done it, and all a lot of us have to play with is making the aforementioned implementations. A lot of the "advanced" things have been put in dll files and not in the source, and I thank InfamousNoone for letting us be able to decompile this one.
The client version is 5017.
|
|
|
07/10/2009, 05:23
|
#4
|
elite*gold: 0
Join Date: Jan 2008
Posts: 1,445
Received Thanks: 1,176
|
The Key3 and the Key4 are made with the first game packet you receive. After you have to use the Key3 and the Key4 for decrypt the packet.
|
|
|
07/10/2009, 06:19
|
#5
|
elite*gold: 0
Join Date: Jul 2009
Posts: 5
Received Thanks: 1
|
Quote:
Originally Posted by CptSky
The Key3 and the Key4 are made with the first game packet you receive. After you have to use the Key3 and the Key4 for decrypt the packet.
|
Thank you, after a closer look, I found that the 3rd and 4th keys are set when the first game packet is received, and not during authorization.
However, I still have my other question.
|
|
|
07/10/2009, 06:30
|
#6
|
elite*gold: 20
Join Date: Jun 2005
Posts: 1,013
Received Thanks: 381
|
If you want an understanding how it works, I'll make it brief
Initially, the client generates two 256-byte keys using a few fixed parameters. The resulting keys are always the same anyway, and you can see them in most sources, but if you wanna know how they're generated.
Code:
_cryptKey1 = new byte[0x100];
_cryptKey2 = new byte[0x100];
Byte iKey1 = 0x9D;
Byte iKey2 = 0x62;
for (int i = 0; i < 0x100; i++)
{
_cryptKey1[i] = iKey1;
_cryptKey2[i] = iKey2;
iKey1 = (byte)((0x0F + (byte)(iKey1 * 0xFA)) * iKey1 + 0x13);
iKey2 = (byte)((0x79 - (byte)(iKey2 * 0x5C)) * iKey2 + 0x6D);
}
The client uses these two encryption keys for all communication to/from the login/account server.
Login consists of providing the server with: Account name, password, server name.
The server replies with: Your account ID, A token, the gameserver IP and port.
Onto connecting to the gameserver.
You send the gameserver you account ID and the token you obtained from the login server. This way the gameserver can authenticate that you are who you say you are. The gameserver obviously links your character to your account ID so it knows who you are, and the token is to prevent someone else logging in as you. Each successful login, a new token is created (randomized) for the login server.
The encryption keys are then changed (for additional poor mans security?) using the SetKeys method. However, only the encryption from the client to the server uses these new keys, but encryption from the server to the client remains unchanged. (Although, counters start from zero here).
The 2 arguments passed to it are actually your Account id and the token.
Code:
public void GenerateKeys(Int32 accountId, Int32 token)
{
Int32 tmpkey1 = (Int32)((((token) + accountId) ^ 0x4321) ^ (token));
Int32 tmpkey2 = (Int32)(tmpkey1 * tmpkey1);
byte[] tmp1 = BitConverter.GetBytes(tmpkey1);
byte[] tmp2 = BitConverter.GetBytes(tmpkey2);
for (int i = 0; i < 256; i++)
{
_cryptKey3[i] = _cryptKey1[i] ^ tmp1[i % 4];
_cryptKey4[i] = _cryptKey2[i] ^ tmp2[i % 4];
}
}
At this point, _cryptKey1 and _cryptKey2 are no longer needed for the said client->server communication, but are still required for the server->client communication.
(I admit,) this was a poor design choice I made. The plan was to contain all the encryption information into a single container, but the communications between server->client and client->server happen to be different enough to warrant separate implementations, and it would've been easier to implement them separately (Would avoid the UsingAlternate crap that had to be added too).
Client versions after v5018 stop using SeyKeys, and the gameserver protocol encryption is replaced by a stronger encryption using Blowfish and a Diffie-Hellman key exchange. The AccountID and token are still sent afterwards to authenticate the account, but no SetKeys(). The reason you probably haven't found any calls to it are because you're looking in server sources for later versions.
There are some more open sources that will expose everything, rather than you having to decompile that dll anyway.
Oh, and since you wanted to know what a packet contains (Although, I hate calling them that, because they're not really "packets" on TCP).
A packet is made up of a header containing: A length (16 bits), and a Type (also 16-bits), followed by the data of length minus 4 bytes (the length included that header). The Type is just a unique numeric value for each different detail communicated. Most people have given names to each one, but they differ between sources.
In addition, after v5018, there's an additional padding on each packet containing "TQClient" or "TQServer".
The content of each packet has changed alot over the versions. I started up a wiki to try keep things organised and "standardize" names, but it wasn't used very well, and isn't kept up to date. Every pserver I've seen so far has managed to: Change the names of things to something less meaningful than they were, and implement the packets in some horrible unmaintainable manner.
|
|
|
07/10/2009, 22:11
|
#7
|
elite*gold: 0
Join Date: Jul 2009
Posts: 5
Received Thanks: 1
|
Thank you very much, unknownone. I've gained a better understanding of how the encryption works, and the process of connecting to the game because of you. The way you explained everything made a lot of sense, and definitely filled in a lot of gaps for me. It's a shame that your wiki wasn't used as well as it was intended to be, I'm sure it would have extremely useful.
Again, thank you for your insight, unknownone, it's greatly appreciated.
|
|
|
07/10/2009, 22:14
|
#8
|
elite*gold: 0
Join Date: Jul 2009
Posts: 548
Received Thanks: 52
|
Quote:
Originally Posted by pipe80
Thank you very much, unknownone. I've gained a better understanding of how the encryption works, and the process of connecting to the game because of you. The way you explained everything made a lot of sense, and definitely filled in a lot of gaps for me. It's a shame that your wiki wasn't used as well as it was intended to be, I'm sure it would have extremely useful.
Again, thank you for your insight, unknownone, it's greatly appreciated.
|
What's a wiki?
|
|
|
07/10/2009, 22:30
|
#9
|
elite*gold: 20
Join Date: Aug 2005
Posts: 1,734
Received Thanks: 1,001
|
Similar to wikipedia where users can create various articles of certain things. The wiki unknownone is talking about is mainly used to contain articles of packets. Their structures ans any enums that it could possibly have.
|
|
|
07/10/2009, 22:49
|
#10
|
elite*gold: 20
Join Date: Jan 2006
Posts: 890
Received Thanks: 241
|
Quote:
Originally Posted by pipe80
I believe the reason you're not going into detail is because you truly don't know yourself.
i know what its for, and how it worked alltho i couldnt have went into detail like unknownone, if you hadn't noticed i never claimed to be good, so no need to 'flame' me for trying to help
By the way, you really should read more carefully.
i dont sit here and read every single post thats posted, therfore its a good assumption that i missed the post by infamous saying you could decompile it if you wanted
|
anyways, gl
|
|
|
07/10/2009, 23:09
|
#11
|
elite*gold: 0
Join Date: Jul 2009
Posts: 5
Received Thanks: 1
|
Quote:
Originally Posted by lostsolder05
anyways, gl
|
I don't know why you would waste your time and not give me a definitive answer.
I didn't flame you. And I don't expect people coming into my thread, spouting off that I go around decompiling other people's "coding" when they don't want it to be. I really don't appreciate that sort of falsified information.
Thank you.
|
|
|
07/10/2009, 23:30
|
#12
|
elite*gold: 20
Join Date: Jan 2006
Posts: 890
Received Thanks: 241
|
Quote:
Originally Posted by pipe80
I don't know why you would waste your time and not give me a definitive answer.
I didn't flame you. And I don't expect people coming into my thread, spouting off that I go around decompiling other people's "coding" when they don't want it to be. I really don't appreciate that sort of falsified information.
Thank you.
|
Quote:
Originally Posted by pipe80
I believe the reason you're not going into detail is because you truly don't know yourself.
i know what its for, and how it worked alltho i couldnt have went into detail like unknownone, if you hadn't noticed i never claimed to be good, so no need to 'flame' me for trying to help
By the way, you really should read more carefully.
i dont sit here and read every single post thats posted, therfore its a good assumption that i missed the post by infamous saying you could decompile it if you wanted
|
By the way, you really should read more carefully.
|
|
|
07/10/2009, 23:34
|
#13
|
elite*gold: 0
Join Date: Jul 2009
Posts: 548
Received Thanks: 52
|
Quote:
Originally Posted by tanelipe
Similar to wikipedia where users can create various articles of certain things. The wiki unknownone is talking about is mainly used to contain articles of packets. Their structures ans any enums that it could possibly have.
|
Can i make my own wiki
|
|
|
 |
Similar Threads
|
[TUT] anthrax28 bypass method(working method)edited by:akomsimojm [TUT]
04/09/2010 - Soldier Front Hacks, Bots, Cheats & Exploits - 36 Replies
SUCROSE anthrax28 bypass method(working method)edited by:akomsimojm
*closed
made another thread that is surely working
|
SocketNetwork - SetKeys question
09/07/2009 - CO2 Private Server - 1 Replies
In Hybrids`s SocketNetwork DLL in the SetKeys void, the byte needs to be CS$0$0000 or it can be anything?
Thanks in advance
|
Importance of not releasing newly discovered opcodes in public
08/04/2008 - Perfect World - 7 Replies
I noticed that the auto detection system of PW server detect changes in the opcodes of the client, opcodes that were released publicly. By realising the opcodes in public the developers of the game could clearly see what opcodes to watch for and look in comparing the changes.
Now i have some opcodes i discovered myself that are not know in public and i modded them in client and the server does detect the changes. They only detect the changes of the changed opcodes that were publicly released...
|
All times are GMT +1. The time now is 06:35.
|
|