Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

W1cked

Member
  • Content Count

    26
  • Joined

  • Last visited

  • Days Won

    3

Everything posted by W1cked

  1. W1cked

    Simple database Migration manager

    Nice! I would also add that migration systems generally come with Up/Down changes. If a migration fails, I would expect the next migration to not run and all other changes be reverted. The reason being is that if I build a table called Users, then a table called Characters that has a foreign key, if Users table fails to execute properly I would expect it to revert all changes and stop all remaining changes. In this case, Characters table would fail to be created due to the foreign key. I like the idea of this as it requires raw queries over some sort of abstract migration system. If I have all of the sql written, it makes it easier if the current migration system becomes abandoned or perhaps a better one is released (I like options.)
  2. W1cked

    SRP6 for higher clients

    Did you run into issues porting Spirited's implementation? It's a pretty well documented source.
  3. W1cked

    File Manager - Encrypt/Decrypt Files

    Trying to decrypt itemtype.dat with 2537. I believe it's the same one in the Client Downloads thread.
  4. W1cked

    File Manager - Encrypt/Decrypt Files

    Does 5017 use something different? I've actually tried using it on multiple different client options and keep getting weird results. I've tried on 5017 and 5615. It's just creating a text file with other non-readable characters.
  5. I've noticed that after being logged in for quite some time that my Xor encrypt function runs out of range. I have tried to debug this for hours now and can't figure it out. It appears that @Spirited's source uses two keys, where I am trying to use one key. I can't figure it out, and I only noticed it now because I left my client running all day and came back to realize that my encrypt function didn't work as expected. It appears to happen around the 2730th time the encrypt function runs. I've attached the code to the playground so you can what I mean. https://play.golang.org/p/HfnKFeqnVh_Z I know it has something to do with with line: dst[i] = dst[i] ^ c.dKey[(c.encrypt>>8)+0x100] More specifically, I know it has something to do with adding 256 (0x100) I'm just not sure why. Below is the same thing on the playground, I've attached it here for archival purposes. package main import ( "encoding/binary" "fmt" ) func main() { x := NewXor() nonEnc := []byte{24, 0, 241, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,} for i := 0; i < 3000; i++ { fmt.Println(i) enc := make([]byte, 24) x.Encrypt(enc, nonEnc) } } // DefaultKey for the Conquer Online game client. Used for interoperability with the game client. var DefaultKey = []byte{0x9D, 0x0F, 0xFA, 0x13, 0x62, 0x79, 0x5C, 0x6D} //Xor cipher used for encrypting/decrypting client/server stream. //dKey is the default key that will be used until the player requests //that the game key (gKey) be initialized using accountId and token. //thereafter, the gKey will be used for encrypting/decrypting. type Xor struct { decrypt, encrypt uint32 dKey [0x200]byte gKey [0x200]byte gameInit bool } // NewCipher assumes the input key is correct (that the length of the key is // 8 bytes) and returns a new instance of the cipher after generating the // initial keystream. func NewXor() *Xor { c := new(Xor) key := DefaultKey for i := 0; i < 0x100; i++ { c.dKey[i] = key[0] c.dKey[i+0x100] = key[4] key[0] = (key[1]+byte(key[0]*key[2]))*key[0] + key[3] key[4] = (key[5]-byte(key[4]*key[6]))*key[4] + key[7] } return c } // GenerateKeys uses the token and identity of the client (in this project, // the 64-bit token buffer from MsgConnect if it were supported by the client // patch) as the key for altering the keystream. func (c *Xor) GenerateKeys(accountId uint32, token uint32) { temp1 := uint32(((token + accountId) ^ 0x4321) ^ token) sqr := uint32(temp1 * temp1) tmp1 := make([]byte, 4) tmp2 := make([]byte, 4) binary.LittleEndian.PutUint32(tmp1, temp1) binary.LittleEndian.PutUint32(tmp2, sqr) for i := 0; i < 0x100; i++ { c.gKey[i] = c.dKey[i] ^ tmp1[i%4] c.gKey[i+0x100] = c.dKey[i + 0x100] ^ tmp2[i%4] } c.gameInit = true c.encrypt = 0 } // Encrypt sets dst with the result of XORing src with the key stream. Dst and // src may be the same slice, but otherwise should not overlap. Decrypt uses // the encryption counter (encrypt). func (c *Xor) Encrypt(dst, src []byte) { for i, v := range src { dst[i] = v ^ 0xAB dst[i] = dst[i]>>4 | dst[i]<<4 dst[i] = dst[i] ^ c.dKey[byte(c.encrypt&0xff)] dst[i] = dst[i] ^ c.dKey[(c.encrypt>>8)+0x100] c.encrypt++ } } // Decrypt sets dst with the result of XORing src with the keystream. Dst and // src may be the same slice, but otherwise should not overlap. Decrypt uses // the decryption counter (decrypt). func (c *Xor) Decrypt(dst, src []byte) { if c.gameInit == false { for i, v := range src { dst[i] = v ^ 0xAB dst[i] = dst[i]>>4 | dst[i]<<4 dst[i] = dst[i] ^ c.dKey[byte(c.decrypt&0xff)] dst[i] = dst[i] ^ c.dKey[(c.decrypt>>8)+0x100] c.decrypt++ } return } for i, v := range src { dst[i] = (byte)(v ^ 0xAB) dst[i] = (byte)(dst[i]>>4 | dst[i]<<4) dst[i] = (byte)(dst[i] ^ c.gKey[c.decrypt&0xff]) dst[i] = (byte)(dst[i] ^ c.gKey[(c.decrypt>>8)+0x100]) c.decrypt++ } } //BlockSize is here to satisfy the cipher.Block interface. It is unimplemented func (c *Xor) BlockSize() int { panic("Xor BlockSize should never be called. Implemented to fulfill interface.") }
  6. W1cked

    [Go] Xor Encryption Issues

    I think what I may have done is copied the functions and rewrote it to match your Comet source, because the code comments don’t look like something I would write. I’m not that detailed. I think really the only thing I did differently was GenerateKeys, and swapped Encrypt/Decrypt to use one key instead of two. Hope you don’t mind me using it. I can’t fully test it til I get back to my PC but it looks like that did the trick!
  7. W1cked

    C# Server Application with Win32

    IMO, if you're worried about performance you should separate the GUI from the server all together. Something like RPC to get server stats/details on a by-need-basis only. This way you're not utilizing resources for the GUI even when you're not even utilizing it.
  8. W1cked

    [Go] Xor Encryption Issues

    So it appears that Comet suffers from the same affliction, which I forgot is where I referenced this cipher, not Chimera. I'm looking in the EO source now though.
  9. W1cked

    [Go] Xor Encryption Issues

    Interesting, 65536 is where it fails. (65536 >> 8 ) + 0x100 would be 512, so 512 is where it's running out of range.
  10. W1cked

    Hello world - Zen

    I'm still working on my server, but progress has slowed down because of time constraints. However, I have learned a lot from it. One of the best places to get (already discovered) information is Spirited's Wiki. You can find a lot of the packet structures there that will get you started. Welcome to the club!
  11. W1cked

    Conquer Map Editor/Creator

    The closest thing I have is a command line dmap reader that I built in Go. I had to have the dmap system in my source for validation anyway, but creating it for command line wasn't that much more difficult. A visual editor on the other hand, like @Spirited said, would probably take a lot of work. I'm actually happy that Ultimation didn't share it, but that's just my opinion.
  12. W1cked

    Hello world

    Hey everyone, I have made a few posts already but I figured I would give an introduction as well. I'm currently in school for Computer Science, and going to hopefully continue until I get my masters in Data Analytics. I'm older than most college students as I chose to serve in the military before going. I've played Conquer for a long time, the earliest that I can remember is that CP's didn't exist, and top + was 8 I believe. I primarily use Go, although I have used C# but mostly just using the Unity library. I'm currently working on a Go 5017 source, but the scope for this is a lot smaller than Spirited's Chimera project. So that's pretty much it, hope to see you all around!
  13. W1cked

    Hello world

    @Spirited Don't worry, my Go code can't be much better. I think we're all pretty critical of ourselves when we look back. I've never looked at my code from 6 months prior and thought "Wow, what a good job." I'm not really sure why I want a Data Analytics, Finance is really where I would like to apply my software skills. Like trading platforms, brokers, or banks. @Omicron @Twelve I'm pretty interested in it, always have been. I've just now been able to find time to actually do something. I hope to have something released soon in 5017 patch. I'm hoping to maybe fix some potential unclean (or what I view as unclean) habits in some sources. My first order of business, in my 5017 server I scraped the idea of switch statements for packet handling. I've created a router, something like a simple http router if you have ever used Go. So instead of having abnormally large switch statements for handling packets, at initialization you specify what "process" goes to the uint16. c.Router.Add(NewRoute().Name(packets.MsgAccountType).Process(MsgAccountProcess)) In my opinion, this makes the code base far more manageable and readable. The router uses a map[uint16]*Route, and the Route contains some information including what process to run for that packet. Since it uses a map, finding the Route happens in constant time (which isn't TOO big of a deal, but it still helps.) I'm hoping to also use something like this for handling some sub actions of packets, like MsgAction.
  14. W1cked

    Packet [1052] Game

    I'm a little confused on why this occurs, and I've looking through a few sources to try to figure it out, but it appears something is occurring that I can't see. I pass packet [1055] from the account server to the client with a uint32 for the Client Identity and another uint32 for the Authentication Code. Identity = 1000000 Auth Code = 2 The client then responds to the account server with [28 0 28 4 64 66 15 0 10 0 0 0 114 101 115 46 100 97 116 0 0 0 0 0 0 0 0 0] Which is packet [1052], with the Identity of 1000000 which appears to be correct. This is where I get lost. The client then connects to the game server, and immediately sends packet [1052]. [28 0 28 4 0 0 0 0 0 0 0 0 0 0 69 110 0 0 0 0 0 0 0 0 0 0 0 0] 28 Length, [1052] Type, and the Identity and additional data are 0's. Why is the client not passing along the identity to the game server?
  15. W1cked

    Packet [1052] Game

    @Spirited that’s what i’ve been using. I’m having to go through sources to find out the sequences. I have the ciphers working (i think) but what i’m struggling with now is that the game crashes when i send the ANSWER_OK packet. I’m guessing that it has something to do with the cipher. I’m trying to debug a couple of sources to figure out what i’m doing different.
  16. W1cked

    Packet [1052] Game

    I am an overly confident programmer who makes simple binary mistakes, and refuses to acknowledge that it could have possibly been me who messed up. This has caused me a great deal of time wasted. I was using the wrong method of the binary littlendian package.
  17. W1cked

    RC5 Package - Go

    I had help from @Spirited to figure this stuff out and port it to Go. I know a lot of people in the emulator communities don't use Go, but I hope with more packages released it will lift the barrier for people to use it. It's pretty straight forward, use the NewRC5 method instead of a struct literal. Encrypt by calling Encrypt and supplying a dst byte slice the same size as the src slice. For Decrypting, do the same thing. This adheres to the Cipher.Block interface, so for your client/conn structs you can just use that interface type. package rc5 import ( "encoding/binary" "math/bits" ) const ( WordSize = 16 Rounds = 12 KeySize = WordSize / 4 SubSize = 2 * (Rounds + 1) ) type RC5 struct { Key []uint32 Sub []uint32 } func NewRC5() RC5 { c := RC5{} c.Key = make([]uint32, KeySize) c.Sub = make([]uint32, SubSize) //Conquer default key c.generateKeys([]byte{ 0x3C, 0xDC, 0xFE, 0xE8, 0xC4, 0x54, 0xD6, 0x7E, 0x16, 0xA6, 0xF8, 0x1A, 0xE8, 0xD0, 0x38, 0xBE, }) return c } func (r *RC5) generateKeys(buf []byte) { //Initialize key expansion //seedLength := len(buf) / WordSize * WordSize for i := 0; i < KeySize; i++ { r.Key[i] = binary.LittleEndian.Uint32(buf[i*4:]) } //Generate r.Sub r.Sub[0] = 0xB7E15163 for i := 1; i < SubSize; i++ { r.Sub[i] = r.Sub[i-1] - 0x61C88647 } //Generate key vector var a, b uint32 var i, j int for x := 0; x < 3*SubSize; x++ { r.Sub[i] = bits.RotateLeft32(r.Sub[i]+(a+b), 3) a = r.Sub[i] r.Key[j] = bits.RotateLeft32(r.Key[j]+(a+b), int(a+b)) b = r.Key[j] i = (i + 1) % SubSize j = (j + 1) % KeySize } } func (r *RC5) Encrypt(dst, src []byte) { length := len(src) / 8 if (len(src) % 8) > 0 { length = length + 1 } copy(dst, src) for word := 0; word < length; word++ { a := binary.LittleEndian.Uint32(dst[8*word:]) + r.Sub[0] b := binary.LittleEndian.Uint32(dst[(8*word + 4):]) + r.Sub[1] for round := 1; round <= Rounds; round++ { a = bits.RotateLeft32(a^b, int(b)) + r.Sub[2*round] b = bits.RotateLeft32(b^a, int(a)) + r.Sub[2*round+1] } binary.LittleEndian.PutUint32(dst[8*word:], a) binary.LittleEndian.PutUint32(dst[8*word+4:], b) } } func (r *RC5) Decrypt(dst, src []byte) { length := len(src) / 8 if (len(src) % 8) > 0 { length = length + 1 } copy(dst, src) for word := 0; word < length; word++ { a := binary.LittleEndian.Uint32(dst[8*word:]) b := binary.LittleEndian.Uint32(dst[(8*word)+4:]) for round := Rounds; round > 0; round-- { b = bits.RotateLeft32(b-r.Sub[2*round+1], -int(a)) ^ a a = bits.RotateLeft32(a-r.Sub[2*round], -int(b)) ^ b } binary.LittleEndian.PutUint32(dst[8*word:], a-r.Sub[0]) binary.LittleEndian.PutUint32(dst[8*word+4:], b-r.Sub[1]) } } func BlockSize() int { return 8 }
  18. W1cked

    RC5 Package - Go

    Thanks! I use Goland, but I don't think I have golint on it. Thank you for the tip!
  19. W1cked

    Go RC5 Cipher Problems

    Nevermind, I was nowhere close. I’ll repost when I make changes.
  20. W1cked

    Go RC5 Cipher Problems

    For future visitors, you can find the completed and functional code at
  21. W1cked

    Go RC5 Cipher Problems

    Using your Comet source I was able to get the Decrypt up and running! Thank you. Question about the Encrypt though. It appears that L112 will throw an OutofRange exception. https://gitlab.com/spirited/comet/blob/master/src/Comet.Network/Security/RC5.cs#L112 Is there a reason why dst is made into a new byte array an eight of the size of the src array?
  22. W1cked

    Legacy TQ Cipher - Optimized Library

    Thanks Cpt! I’ve been using your Cops source for reference on my 5017 Go project! Your source is definitely a lot cleaner and easier to follow than a lot of sources.
  23. W1cked

    Go RC5 Cipher Problems

    5017
  24. W1cked

    Go RC5 Cipher Problems

    I'm not very well versed in C#, so some of the things I was porting I took guesses on. Everything compiles, but the resulting bytes are definitely not correct. For password "test" I get 45 253 45 253 0 0 0 0 0 0 0 0 0 0 0 0 as a result after RC5 "decrypt" Also, I can rewrite this to fit the cipher interface. I do like that, and it is more "idiomatic" than mine is by far. package rc5 import "errors" const ( RC5_PW32 = 0xB7E15163 RC5_QW32 = 0x61C88647 RC5_32 = 32 RC5_12 = 12 RC5_SUB = RC5_12*2 + 2 RC5_16 = 16 RC5_KEY = RC5_16 / 4 ) type RC5 struct { mKey [RC5_KEY]uint32 mSub [RC5_SUB]uint32 } /// CO2: { 0x3C, 0xDC, 0xFE, 0xE8, 0xC4, 0x54, 0xD6, 0x7E, 0x16, 0xA6, 0xF8, 0x1A, 0xE8, 0xD0, 0x38, 0xBE } func NewRC5(seed []byte) (RC5, error) { c := RC5{} if len(seed) != 16 { return c, errors.New("seed does not have expected 16 bytes") } for z := 0; z < RC5_KEY; z++ { c.mKey[z] = uint32(seed[z]) } c.mSub[0] = RC5_PW32 for i := 1; i < RC5_SUB; i++ { c.mSub[i] = c.mSub[i-1] - RC5_QW32 } i, j, x, y := uint32(0), uint32(0), uint32(0), uint32(0) count := 3 * Max(RC5_KEY, RC5_SUB) for k := 0; k < count; k++ { c.mSub[i] = rotl(uint32(c.mSub[i]+x+y), 3) x = c.mSub[i] i = (i + 1) % RC5_SUB c.mKey[j] = rotl((c.mKey[j] + x + y), x+y) y = c.mKey[j] j = (j + 1) % RC5_KEY } return c, nil } func (rc *RC5) Decrypt(buf *[]byte, length int) { leng := length / 8 for k := 0; k < leng; k++ { lv := uint32(buf[2*k]) rv := uint32(buf[2*k+1]) for i := RC5_12; i >= 1; i-- { rv = rotr((rv - rc.mSub[2*i+1]), lv) ^ lv lv = rotr((lv - rc.mSub[2*i]), rv) ^ rv } buf[2*k] = byte(lv - rc.mSub[0]) buf[2*k+1] = byte(rv - rc.mSub[1]) } } func rotl(aValue uint32, aCount uint32) uint32 { leftShift := uint32(aCount % 32) rightShift := 32 - leftShift return (aValue << leftShift) | (aValue >> rightShift) } func rotr(aValue uint32, aCount uint32) uint32 { rightShift := uint32(aCount % 32) leftShift := 32 - rightShift return (aValue >> rightShift) | (aValue << leftShift) } func Min(x, y int) int { if x < y { return x } return y } func Max(x, y int) int { if x > y { return x } return y }
  25. W1cked

    Go RC5 Cipher Problems

    Hey Spirited, that’s actually what I tried to use initially. Then i tried to port CptSky’s but I think I was way off. I’ll post it again. As for the Go package you posted, would it not work directly? I tried using it directly, but perhaps I was doing something wrong?
×

Important Information

By using this site, you agree to our Terms of Use.