[uokr_infos.txt]
UO:KR uses AES in CFB mode (IV of 16byte and a Key of 32 byte) for Network Encryption.

1. We need to get an IV of 16byte and a Key of 32 byte from e3 and e4 packets
1a. IV in first e3 is the last 0x10 bytes
1b. key is sha256(math-transform(constbytes,packets)))
1c. math-transorm is ???
2. Create a AES object in CFB mode
3. xor the plaintext with the blockcypher to get the crypt packed.

To break it:

// uokr client, processxorblock asm:				// In this column the riced (no crypt) version
006E6DA0  |. 85C9           TEST ECX,ECX
006E6DA2  |. 885D DE        MOV BYTE PTR SS:[EBP-22],BL
006E6DA5  |. 8A9E 0089A400  MOV BL,BYTE PTR DS:[ESI+A48900]
006E6DAB  |. 885D DF        MOV BYTE PTR SS:[EBP-21],BL
006E6DAE  |. 74 32          JE SHORT UOKR.006E6DE2		// NOP
006E6DB0  |. 8B30           MOV ESI,DWORD PTR DS:[EAX] 		// NOP
006E6DB2  |. 3331           XOR ESI,DWORD PTR DS:[ECX]		// NOP
006E6DB4  |. 8B55 10        MOV EDX,DWORD PTR SS:[EBP+10]	// MOV EDX,DWORD PTR SS:[EBP+10]
006E6DB7  |. 3375 D4        XOR ESI,DWORD PTR SS:[EBP-2C]	// NOP
006E6DBA  |. 8932           MOV DWORD PTR DS:[EDX],ESI		// MOV DWORD PTR DS:[EDX],0h
006E6DBC  |. 8B70 04        MOV ESI,DWORD PTR DS:[EAX+4]	// NOP
006E6DBF  |. 3371 04        XOR ESI,DWORD PTR DS:[ECX+4]	// NOP
006E6DC2  |. 3375 D8        XOR ESI,DWORD PTR SS:[EBP-28]	// NOP
006E6DC5  |. 8972 04        MOV DWORD PTR DS:[EDX+4],ESI	// MOV DWORD PTR DS:[EDX+4],0h
006E6DC8  |. 8B70 08        MOV ESI,DWORD PTR DS:[EAX+8]	// NOP
006E6DCB  |. 3371 08        XOR ESI,DWORD PTR DS:[ECX+8]	// NOP
006E6DCE  |. 3375 DC        XOR ESI,DWORD PTR SS:[EBP-24]	// NOP
006E6DD1  |. 8972 08        MOV DWORD PTR DS:[EDX+8],ESI	// MOV DWORD PTR DS:[EDX+8],0h
006E6DD4  |. 8B40 0C        MOV EAX,DWORD PTR DS:[EAX+C]	// NOP
006E6DD7  |. 3341 0C        XOR EAX,DWORD PTR DS:[ECX+C]	// NOP
006E6DDA  |. 3345 E0        XOR EAX,DWORD PTR SS:[EBP-20]	// NOP
006E6DDD  |. 8942 0C        MOV DWORD PTR DS:[EDX+C],EAX	// MOV DWORD PTR DS:[EDX+C],0h
006E6DE0  |. EB 25          JMP SHORT UOKR.006E6E07		// NOP
006E6DE2  |> 8B10           MOV EDX,DWORD PTR DS:[EAX]		// NOP
006E6DE4  |. 3355 D4        XOR EDX,DWORD PTR SS:[EBP-2C]	// NOP
006E6DE7  |. 8B4D 10        MOV ECX,DWORD PTR SS:[EBP+10]	// NOP
006E6DEA  |. 8911           MOV DWORD PTR DS:[ECX],EDX		// NOP
006E6DEC  |. 8B50 04        MOV EDX,DWORD PTR DS:[EAX+4]	// NOP
006E6DEF  |. 3355 D8        XOR EDX,DWORD PTR SS:[EBP-28]	// NOP
006E6DF2  |. 8951 04        MOV DWORD PTR DS:[ECX+4],EDX	// NOP
006E6DF5  |. 8B50 08        MOV EDX,DWORD PTR DS:[EAX+8]	// NOP
006E6DF8  |. 3355 DC        XOR EDX,DWORD PTR SS:[EBP-24]	// NOP
006E6DFB  |. 8951 08        MOV DWORD PTR DS:[ECX+8],EDX	// NOP
006E6DFE  |. 8B40 0C        MOV EAX,DWORD PTR DS:[EAX+C]	// NOP
006E6E01  |. 3345 E0        XOR EAX,DWORD PTR SS:[EBP-20]	// NOP
006E6E04  |. 8941 0C        MOV DWORD PTR DS:[ECX+C],EAX	// NOP
006E6E07  |> 5F             POP EDI
006E6E08  |. 5E             POP ESI
006E6E09  |. 5B             POP EBX
006E6E0A  |. C9             LEAVE
006E6E0B  \. C2 0C00        RETN 0C


// Login crypt

005E2237   . 8A4E 04        MOV CL,BYTE PTR DS:[ESI+4]
005E223A   . 3008           XOR BYTE PTR DS:[EAX],CL
005E223C   . 8B4E 04        MOV ECX,DWORD PTR DS:[ESI+4]
005E223F   . 8B46 08        MOV EAX,DWORD PTR DS:[ESI+8]
005E2242   . 8BD0           MOV EDX,EAX
005E2244   . D1E8           SHR EAX,1

Patch @005E223A 0x90 0x90

// ------------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------------


I did some reversing over the last two days and reversed how the game server encryption of UO:KR works.

As was said before, UO:KR uses AES/CFB/NoPadding for game server encryption. What was not yet known was the 
meaning of the E3 and E4 packets and how the encryption key is calculated.

First off, the structure of the 0xE3 packet:
Code:

byte[1] packet cmd (0xe3)
byte[2] packet length
byte[4] length base
byte[length base] base
byte[4] length prime
byte[length prime] prime
byte[4] length public key
byte[length public key] public key
byte[4] unkD (0x00000020)
byte[4] length iv
byte[length iv] iv


Then the 0xE4 structure:
Code:

byte[1] packet cmd (0xe4)
byte[2] packet length
byte[4] length public key
byte[length public key] public key


Now for the details:
Ultima Online now uses strong cryptography for game server encryption (Why not for login?). Diffie-Hellman-Merkle 
is used to exchange a symmetric cipher key in a secure way. The 0xE3 packet is the first key agreement packet and 
contains the information required by the client to obtain the secret session key.

The base for diffie hellman is represented as an ASN.1 BER encoded integer (The original dump said 02 01 03, 
which is just 3 encoded using the BER).

The prime is also represented as a BER encoded integer.

The public key is just the binary representation of the public key. No BER encoding here. 
(This is a peculiarity of the Crypto++ interface for DH).

The last unknown element could possibly be the AES key size although I don't know why it is included in the packet...

After receiving 0xE3, the client generates his private and public key from the prime/base received by the server. 
(He chooses a random number for this). He then proceeds to calculate the secret session key and sends his 
public key to the server (packet 0xE4).

The client has a hardcoded prime, base, public and private key on the stack of the initialization function and 
proceeds to compute a diffie hellman session key from this information. The values currently used in the client are:
Base: 3 (As in the dynamic data)
Prime: 00 c7 77 96 c9 ea 6a 9e 9f 71 a7 27 19 d6 77 80 43
Private Key: 00 00 00 00 00 00 00 00 02 B3 43 65 0B 45 D4 AA
Public Key: 72 0E EF C3 38 13 27 5A 18 F8 AB 8A 24 68 CE 62

The resulting static session key is: 26 5D E0 9A D8 C9 1F 51 8B 62 6D 16 72 4B 83 A3

To get the AES encryption key, SHA256(static secret | dynamic secret) is computed and used directly as the 
256bit key for AES as mentioned above.

If you need a proof of concept implemented in Java, feel free to ask.