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?
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
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.
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.
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.
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.
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.
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.
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.
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
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.
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.
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.
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...