Author | Message | Time |
---|---|---|
Insolence | I'm just getting into Reverse Engineering, and I know a little C#. I bought and (tried to) read Reversing: Secrets of Reverse Engineering, so if there's anything from that book I should examine more deeply, let me know :) Anyway, I'm trying to reverse a packet encryption function for an online game, I wrote a C# program that uses SharpPcap to capture and filter packets. With some help from my friend AntiRush I put a BP on WSARecv and I looked at the first few functions on the stack, and found this:[code]004DBD46 |. 7D 12 JGE SHORT magic1.004DBD5A 004DBD48 |. 50 PUSH EAX 004DBD49 |. 68 44635700 PUSH magic1.00576344 ; ASCII "padDecrypt error %d" 004DBD4E |. E8 F0F0FFFF CALL magic1.004DAE43[/code] I'm assuming that's where the packet is decrypted. So, I googled padDecrypt and apparently it has to do with Rijndael encryption. I went ahead and googled that too, and found that .NET has a RijndaelManaged class already built and setup for me. Am I going too far to assume that this is the same encryption method used with this program? Anyway, I wrote up some code to do Rijndael decrypting, but I noticed you need a "salt" along with the packet bytes. I'm trying to figure out how to get the salt, I'm surprised I've gotten this far. Here's the whole decryption function: [code]004DC22F 85C0 TEST EAX,EAX 004DC231 7E 06 JLE SHORT magic1.004DC239 004DC233 0183 88000000 ADD DWORD PTR DS:[EBX+88],EAX 004DC239 0105 FC539E01 ADD DWORD PTR DS:[19E53FC],EAX 004DC23F 0143 68 ADD DWORD PTR DS:[EBX+68],EAX 004DC242 8B93 88000000 |MOV EDX,DWORD PTR DS:[EBX+88] 004DC248 3BD7 CMP EDX,EDI 004DC24A 0F8C 03020000 JL magic1.004DC453 004DC250 8B4B 78 MOV ECX,DWORD PTR DS:[EBX+78] 004DC253 0FB641 01 MOVZX EAX,BYTE PTR DS:[ECX+1] 004DC257 0FB631 MOVZX ESI,BYTE PTR DS:[ECX] 004DC25A C1E0 08 SHL EAX,8 004DC25D 03C6 ADD EAX,ESI 004DC25F 3B83 8C000000 CMP EAX,DWORD PTR DS:[EBX+8C] 004DC265 8945 FC MOV DWORD PTR SS:[EBP-4],EAX 004DC268 0F8F E1010000 JG magic1.004DC44F 004DC26E 3BC2 CMP EAX,EDX 004DC270 7E 23 JLE SHORT magic1.004DC295 004DC272 2BC2 SUB EAX,EDX 004DC274 50 PUSH EAX 004DC275 03D1 ADD EDX,ECX 004DC277 52 PUSH EDX 004DC278 8BF3 MOV ESI,EBX 004DC27A E8 161A0000 CALL magic1.004DDC95 004DC27F > 85C0 TEST EAX,EAX 004DC281 7E 06 JLE SHORT magic1.004DC289 004DC283 0183 88000000 ADD DWORD PTR DS:[EBX+88],EAX 004DC289 0105 FC539E01 ADD DWORD PTR DS:[19E53FC],EAX 004DC28F 0143 68 ADD DWORD PTR DS:[EBX+68],EAX 004DC292 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 004DC295 3B83 88000000 CMP EAX,DWORD PTR DS:[EBX+88] 004DC29B 0F85 B2010000 JNZ magic1.004DC453 004DC2A1 8B53 54 MOV EDX,DWORD PTR DS:[EBX+54] 004DC2A4 83A3 88000000 00 AND DWORD PTR DS:[EBX+88],0 004DC2AB 85D2 TEST EDX,EDX 004DC2AD 75 20 JNZ SHORT magic1.004DC2CF 004DC2AF 8B4B 78 MOV ECX,DWORD PTR DS:[EBX+78] 004DC2B2 66:8179 0A FFFF CMP WORD PTR DS:[ECX+A],0FFFF 004DC2B8 75 0D JNZ SHORT magic1.004DC2C7 004DC2BA 8B03 MOV EAX,DWORD PTR DS:[EBX] 004DC2BC 51 PUSH ECX 004DC2BD 8BCB MOV ECX,EBX 004DC2BF FF50 20 CALL DWORD PTR DS:[EAX+20] 004DC2C2 E9 A3010000 JMP magic1.004DC46A 004DC2C7 85D2 TEST EDX,EDX 004DC2C9 0F84 9B010000 JE magic1.004DC46A 004DC2CF 8BB3 80000000 MOV ESI,DWORD PTR DS:[EBX+80] 004DC2D5 8B4B 78 MOV ECX,DWORD PTR DS:[EBX+78] 004DC2D8 56 PUSH ESI 004DC2D9 83C0 FE ADD EAX,-2 004DC2DC 03CF ADD ECX,EDI 004DC2DE 50 PUSH EAX 004DC2DF E8 90950300 CALL magic1.00515874 004DC2E4 85C0 TEST EAX,EAX 004DC2E6 7D 12 JGE SHORT magic1.004DC2FA 004DC2E8 50 PUSH EAX 004DC2E9 68 34645700 PUSH magic1.00576434 ; ASCII "padDecrypt error %d" 004DC2EE > E8 F0F0FFFF CALL magic1.004DB3E3 004DC2F3 59 POP ECX 004DC2F4 59 POP ECX 004DC2F5 E9 55010000 JMP magic1.004DC44F 004DC2FA F643 2C 80 TEST BYTE PTR DS:[EBX+2C],80 004DC2FE 0F84 D7000000 JE magic1.004DC3DB 004DC304 8B83 80000000 MOV EAX,DWORD PTR DS:[EBX+80] 004DC30A 0FB610 MOVZX EDX,BYTE PTR DS:[EAX] 004DC30D 33C9 XOR ECX,ECX 004DC30F 8A48 01 MOV CL,BYTE PTR DS:[EAX+1] 004DC312 83C0 02 ADD EAX,2 004DC315 84C9 TEST CL,CL 004DC317 79 26 JNS SHORT magic1.004DC33F 004DC319 83E1 7F AND ECX,7F 004DC31C C1E1 08 SHL ECX,8 004DC31F 03CA ADD ECX,EDX 004DC321 8BF1 MOV ESI,ECX 004DC323 56 PUSH ESI 004DC324 50 PUSH EAX 004DC325 8B43 78 MOV EAX,DWORD PTR DS:[EBX+78] 004DC328 83C0 08 ADD EAX,8 004DC32B 50 PUSH EAX 004DC32C E8 EF2B0600 CALL magic1.0053EF20 004DC331 83C4 0C ADD ESP,0C 004DC334 83C6 02 ADD ESI,2 004DC337 8975 FC MOV DWORD PTR SS:[EBP-4],ESI 004DC33A E9 AD000000 JMP magic1.004DC3EC 004DC33F 8365 FC 00 AND DWORD PTR SS:[EBP-4],0 004DC343 0FB6C9 MOVZX ECX,CL 004DC346 C1E1 08 SHL ECX,8 004DC349 03CA ADD ECX,EDX 004DC34B 8B93 8C000000 MOV EDX,DWORD PTR DS:[EBX+8C] 004DC351 83EA 08 SUB EDX,8 004DC354 52 PUSH EDX 004DC355 8D55 FC LEA EDX,DWORD PTR SS:[EBP-4] 004DC358 52 PUSH EDX 004DC359 51 PUSH ECX 004DC35A 894D F8 MOV DWORD PTR SS:[EBP-8],ECX 004DC35D 8B4B 78 MOV ECX,DWORD PTR DS:[EBX+78] 004DC360 83C1 08 ADD ECX,8 004DC363 50 PUSH EAX 004DC364 E8 E4430000 CALL magic1.004E074D 004DC369 83C4 10 ADD ESP,10 004DC36C EB 5E JMP SHORT magic1.004DC3CC 004DC36E 8BBB 8C000000 MOV EDI,DWORD PTR DS:[EBX+8C] 004DC374 81C7 00100000 ADD EDI,1000 004DC37A E8 61D7F2FF CALL magic1.00409AE0 004DC37F FFB3 8C000000 PUSH DWORD PTR DS:[EBX+8C] 004DC385 8BF8 MOV EDI,EAX 004DC387 FF73 78 PUSH DWORD PTR DS:[EBX+78] 004DC38A 57 PUSH EDI 004DC38B E8 902B0600 CALL magic1.0053EF20 004DC390 8B73 78 MOV ESI,DWORD PTR DS:[EBX+78] 004DC393 E8 684CF2FF CALL magic1.00401000 004DC398 8183 8C000000 00>ADD DWORD PTR DS:[EBX+8C],1000 004DC3A2 897B 78 MOV DWORD PTR DS:[EBX+78],EDI 004DC3A5 8B83 8C000000 MOV EAX,DWORD PTR DS:[EBX+8C] 004DC3AB 83E8 08 SUB EAX,8 004DC3AE 50 PUSH EAX 004DC3AF 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4] 004DC3B2 50 PUSH EAX 004DC3B3 8B83 80000000 MOV EAX,DWORD PTR DS:[EBX+80] 004DC3B9 FF75 F8 PUSH DWORD PTR SS:[EBP-8] 004DC3BC 8BCF MOV ECX,EDI 004DC3BE 83C1 08 ADD ECX,8 004DC3C1 40 INC EAX 004DC3C2 40 INC EAX 004DC3C3 50 PUSH EAX 004DC3C4 E8 84430000 CALL magic1.004E074D 004DC3C9 83C4 1C ADD ESP,1C 004DC3CC 85C0 TEST EAX,EAX 004DC3CE ^75 9E JNZ SHORT magic1.004DC36E 004DC3D0 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 004DC3D3 83C0 02 ADD EAX,2 004DC3D6 8945 FC MOV DWORD PTR SS:[EBP-4],EAX 004DC3D9 EB 11 JMP SHORT magic1.004DC3EC 004DC3DB 50 PUSH EAX 004DC3DC 8B43 78 MOV EAX,DWORD PTR DS:[EBX+78] 004DC3DF 83C0 08 ADD EAX,8 004DC3E2 56 PUSH ESI 004DC3E3 50 PUSH EAX 004DC3E4 E8 372B0600 CALL magic1.0053EF20 004DC3E9 83C4 0C ADD ESP,0C 004DC3EC 8B73 78 MOV ESI,DWORD PTR DS:[EBX+78] 004DC3EF 8B4D FC MOV ECX,DWORD PTR SS:[EBP-4] 004DC3F2 8D7E 0A LEA EDI,DWORD PTR DS:[ESI+A] 004DC3F5 83C1 FC ADD ECX,-4 004DC3F8 8BD7 MOV EDX,EDI 004DC3FA E8 1CFCFFFF CALL magic1.004DC01B 004DC3FF 66:3946 08 CMP WORD PTR DS:[ESI+8],AX 004DC403 74 54 JE SHORT magic1.004DC459 004DC405 FF75 FC PUSH DWORD PTR SS:[EBP-4] 004DC408 68 0C645700 PUSH magic1.0057640C ; ASCII "ERROR: packet checksum failed, pktln=%d" 004DC40D E8 D1EFFFFF CALL magic1.004DB3E3 004DC412 0FB707 MOVZX EAX,WORD PTR DS:[EDI] 004DC415 50 PUSH EAX 004DC416 68 FC635700 PUSH magic1.005763FC ; ASCII "p->PktType = %d" 004DC41B E8 C3EFFFFF CALL magic1.004DB3E3 004DC420 0FB606 MOVZX EAX,BYTE PTR DS:[ESI] 004DC423 50 PUSH EAX 004DC424 68 E8635700 PUSH magic1.005763E8 ; ASCII "p->SizeBuf[0] = %d" 004DC429 E8 B5EFFFFF CALL magic1.004DB3E3 004DC42E 0FB646 01 MOVZX EAX,BYTE PTR DS:[ESI+1] 004DC432 50 PUSH EAX 004DC433 68 D4635700 PUSH magic1.005763D4 ; ASCII "p->SizeBuf[1] = %d" 004DC438 E8 A6EFFFFF CALL magic1.004DB3E3 004DC43D 0FB646 02 MOVZX EAX,BYTE PTR DS:[ESI+2] 004DC441 50 PUSH EAX 004DC442 68 C0635700 PUSH magic1.005763C0 ; ASCII "p->RoutingType = %d" 004DC447 E8 97EFFFFF CALL magic1.004DB3E3 004DC44C 83C4 28 ADD ESP,28 004DC44F 834B 2C 01 OR DWORD PTR DS:[EBX+2C],1 004DC453 33C0 XOR EAX,EAX 004DC455 5F POP EDI 004DC456 5E POP ESI 004DC457 C9 LEAVE 004DC458 C3 RETN[/code] EDIT: Also, thanks for reading and/or replying to this thread, I appreciate it :D EDIT: And here's my Rijndael implementation: [code] RijndaelManaged RijndaelCipher = new RijndaelManaged(); byte[] EncryptedData = packet.Bytes; byte[] Salt = new byte[5];//UNKNOWN; PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(EncryptedData, Salt); // Create a decryptor from the existing SecretKey bytes. ICryptoTransform Decryptor = RijndaelCipher.CreateDecryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16)); MemoryStream memoryStream = new MemoryStream(EncryptedData); // Create a CryptoStream. (always use Read mode for decryption). CryptoStream cryptoStream = new CryptoStream(memoryStream, Decryptor, CryptoStreamMode.Read); // Since at this point we don't know what the size of decrypted data // will be, allocate the buffer long enough to hold EncryptedData; // DecryptedData is never longer than EncryptedData. byte[] PlainText = new byte[EncryptedData.Length]; // Start decrypting. int DecryptedCount = cryptoStream.Read(PlainText, 0, PlainText.Length-4); memoryStream.Close(); cryptoStream.Close(); // Convert decrypted data into a string. string DecryptedData = Encoding.Unicode.GetString(PlainText, 0, DecryptedCount);[/code] Update: I'm completely wrong about this. That is just the packet filtering thing, not decryption, at least I don't think so. I think this has to be where the decryption is happening: [code]004DC2C2 E9 A3010000 JMP magic1.004DC46A 004DC2C7 85D2 TEST EDX,EDX 004DC2C9 0F84 9B010000 JE magic1.004DC46A 004DC2CF 8BB3 80000000 MOV ESI,DWORD PTR DS:[EBX+80] 004DC2D5 8B4B 78 MOV ECX,DWORD PTR DS:[EBX+78] 004DC2D8 56 PUSH ESI ; Param 1 004DC2D9 83C0 FE ADD EAX,-2 004DC2DC 03CF ADD ECX,EDI 004DC2DE 50 PUSH EAX ; Param 2 004DC2DF E8 90950300 CALL magic1.00515874 ; Decryption 004DC2E4 85C0 TEST EAX,EAX 004DC2E6 7D 12 JGE SHORT magic1.004DC2FA 004DC2E8 50 PUSH EAX 004DC2E9 68 34645700 PUSH magic1.00576434 ; ASCII "padDecrypt error %d" [/code] I assume magic1.00515874 is the padDecrypt function, but I don't understand what it's returning. I also don't understand what parameters are being passed to it, ESI and EAX? I couldn't find any padDecrypt functions online that took two parameters, but I'm assuming it's a specialized function inside a class with they key set as a property. Something like [code]byte[] padDecrypt(byte[] packet, byte[] outbuffer) { Salt theSalt = this.Salt; //....etc. }[/code] Edit: [code]004DC2CF 8BB3 80000000 MOV ESI,DWORD PTR DS:[EBX+80] 004DC2D5 8B4B 78 MOV ECX,DWORD PTR DS:[EBX+78] 004DC2D8 56 PUSH ESI ; Param 1 004DC2D9 83C0 FE ADD EAX,-2 004DC2DC 03CF ADD ECX,EDI 004DC2DE 50 PUSH EAX ; Param 2[/code]Based on that book, EBX seems to be a class, something like this [code]struct Something { UNKNOWN Member1; // [EBX+78] UNKNOWN Member2; // [EBX+80] }[/code] I'll look through and try to find out where they get EBX from. Edit#2: Found two other members, I suppose: [code]struct Something { UNKNOWN Member1; // [EBX+68] UNKNOWN Member2; // [EBX+78] UNKNOWN Member3; // [EBX+80] UNKNOWN Member4; // [EBX+88] }[/code] Edit #3: I'm going to assume it's the packet class, because of these guys: [code]004DC3FF 66:3946 08 CMP WORD PTR DS:[ESI+8],AX 004DC403 74 54 JE SHORT magic1.004DC459 004DC405 FF75 FC PUSH DWORD PTR SS:[EBP-4] 004DC408 68 0C645700 PUSH magic1.0057640C ; ASCII "ERROR: packet checksum failed, pktln=%d" 004DC40D E8 D1EFFFFF CALL magic1.004DB3E3 004DC412 0FB707 MOVZX EAX,WORD PTR DS:[EDI] 004DC415 50 PUSH EAX 004DC416 68 FC635700 PUSH magic1.005763FC ; ASCII "p->PktType = %d" 004DC41B E8 C3EFFFFF CALL magic1.004DB3E3 004DC420 0FB606 MOVZX EAX,BYTE PTR DS:[ESI] 004DC423 50 PUSH EAX 004DC424 68 E8635700 PUSH magic1.005763E8 ; ASCII "p->SizeBuf[0] = %d" 004DC429 E8 B5EFFFFF CALL magic1.004DB3E3 004DC42E 0FB646 01 MOVZX EAX,BYTE PTR DS:[ESI+1] 004DC432 50 PUSH EAX 004DC433 68 D4635700 PUSH magic1.005763D4 ; ASCII "p->SizeBuf[1] = %d" 004DC438 E8 A6EFFFFF CALL magic1.004DB3E3 004DC43D 0FB646 02 MOVZX EAX,BYTE PTR DS:[ESI+2] 004DC441 50 PUSH EAX 004DC442 68 C0635700 PUSH magic1.005763C0 ; ASCII "p->RoutingType = %d" [/code] I also noticed in my first post the disassembled method is cut off early, I left out the code after the switch/case statements, I think. Fixed that. I added more members I found, and infered their values from above: [code]struct Packet { UNKNOWN Member1; // [EBX+54] UNKNOWN Member2; // [EBX+68] WORD SizeBuf; // [EBX+78] WORD RoutingType; // [EBX+80] BYTE[?] PktType; // [EBX+82] UNKNOWN Member5; // [EBX+88] UNKNOWN Member6; // [EBX+2C] UNKNOWN Member7; // [EBX+8C] }[/code] Edit #3: [code]004DC4AA . B9 8C635700 MOV ECX,magic1.0057638C ; ASCII "0xd4a0ba0250b6fd2ec626e7efd637df76c716e22d0944b88b" [/code] I was researching that constant ASCII hex value, and apparently it's a prime public key (I think). So, from that I need to make a private key to decrypt the AES (Rijindael(sp)) stuff. | May 27, 2007, 9:18 PM |
warz | What game is this, if you don't mind me asking? | May 27, 2007, 11:02 PM |
Insolence | Oh, of course I don't mind--Magic The Gathering: Online :) | May 27, 2007, 11:07 PM |