Looking for some help with blowfish

Programming related discussions related to game research
MrMe
Posts: 11
Joined: Thu Jan 18, 2018 7:56 pm

Looking for some help with blowfish

Post by MrMe »

I am reverse engineering a game that has been dead for a while and am currently working on figuring out how their packet encryption works.
Almost have it complete but I am having trouble understanding a piece of (decompiled) code.

I'll explain the flow of the program so you have an idea of what is going on.

Flow
Step 1 - unencrypted payload

Memory space at packet payload location before encryption.
I suspect that "08 00" is payload length, "01 00" is packet id, "20 FB 19 00" is unknown and "70 00 00 00 6C D4 19 00" is not actually part of the payload here.

Code: Select all

0019D39C  08 00 01 00 20 FB 19 00 70 00 00 00 6C D4 19 00


Step 2 - encryption starts (encryptPacket1)
The function encryptPacket1(ptr buffer from step 1, 8, 0, 0) is called. (https://i.imgur.com/fuPzjen.png)
constant_2755 is set to "2755" after the blowfish key has been initialized.


Step 2.1 - 8 bytes get appended to the packet (sub_63A180)
In step 2 it calls sub_63A180(8, ptr buffer from step 1) (https://i.imgur.com/d3htpi8.png)
constant_156 is set to 0x9C (156) in the binary and never changes, not sure why IDA thinks it is an array. See data here (https://i.imgur.com/3Qe2cJM.png).
Memory space after subroutine has been executed.

Code: Select all

0019D39C  08 00 01 00 20 FB 19 00 94 14 EC 29 D2 4E 06 00


Step 2.2 - pre-blowfish block encryption (sub_63AD20)
In step 2.1 it calls sub_63AD20(ptr buffer from step 1, 16) (https://i.imgur.com/RF4iFNN.png)
Code of blowfish_encryptBlock (https://i.imgur.com/U5bIxq2.png)

Memory space after first loop. (first 8 bytes changed)

Code: Select all

0019D39C  C3 86 06 B6 80 03 0E 05 94 14 EC 29 D2 4E 06 00

Memory space after second loop. (last 8 bytes changed)

Code: Select all

0019D39C  C3 86 06 B6 80 03 0E 05 34 AF 97 2A 83 6F 72 CF


Step 3 - Rounding up
The packet gets an header (https://i.imgur.com/mkotNk6.png) with an unknown "03" byte.

This is the packet I end up receiving.

Code: Select all

14 00 03 0E C3 86 06 B6 80 03 0E 05 34 AF 97 2A 83 6F 72 CF


"14 00" is the packet length (20).
"03" is unknown.
"0E" is the last byte of the checksum (927D3B0E) of the payload.
"C3 86 06 B6 80 03 0E 05 34 AF 97 2A 83 6F 72 CF" is the payload.

Help I am looking for
The blowfish key is "66642423323E34357D5F7E2E33384C6160272B52452F252D49613D7C3958283F00" in hex, this has been verified by checking initial pary by stepping after set key in a debugger and compare it with a c# blowfish implementation using the key. It is 33 characters in size.

I have no idea what is happening in step "Step 2.1" and why. Tried looking at various blowfish implementations but none of them seem to do that.

Also my c# code fails to reproduce anything of "Step 2.2".
Used the c# file listed here https://defuse.ca/blowfish.htm.

Code: Select all

var blowfish = new BlowFish("66642423323E34357D5F7E2E33384C6160272B52452F252D49613D7C3958283F00");

const string packetUnencrypted = "0800010020FB1900";

Console.WriteLine(BitConverter.ToString(blowfish.Encrypt_ECB(BlowFish.HexToByte(packetUnencrypted))));

Output is always "F2 D1 B4 8B 36 F4 C8 93" instead of "C3 86 06 B6 80 03 0E 05".

Same goes for decryption, I can't decrypt the last 16 bytes of the packet (using the same blowfish lib).

Any help would be really appreciated!
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Looking for some help with blowfish

Post by aluigi »

Here it works:

Code: Select all

encryption blowfish "\x66\x64\x24\x23\x32\x3E\x34\x35\x7D\x5F\x7E\x2E\x33\x38\x4C\x61\x60\x27\x2B\x52\x45\x2F\x25\x2D\x49\x61\x3D\x7C\x39\x58\x28\x3F\x00" "" 1
log "dump.dat" 0 8

The reason is that blowfish is usually interpreted with two different endianess.
bf_ecb in openssl gives the result you have there while other blowfish implementations (like "encryption blowfish" in quickbms) do the opposite, in fact if you use bf_ecb in the above script you have your same result.
MrMe
Posts: 11
Joined: Thu Jan 18, 2018 7:56 pm

Re: Looking for some help with blowfish

Post by MrMe »

aluigi wrote:Here it works:

Code: Select all

encryption blowfish "\x66\x64\x24\x23\x32\x3E\x34\x35\x7D\x5F\x7E\x2E\x33\x38\x4C\x61\x60\x27\x2B\x52\x45\x2F\x25\x2D\x49\x61\x3D\x7C\x39\x58\x28\x3F\x00" "" 1
log "dump.dat" 0 8

The reason is that blowfish is usually interpreted with two different endianess.
bf_ecb in openssl gives the result you have there while other blowfish implementations (like "encryption blowfish" in quickbms) do the opposite, in fact if you use bf_ecb in the above script you have your same result.


Thank you! Could you tell me in what part of the algorithm the endianess is so important? If I have to guess it is where it converts the left and right from 8 bytes to 2 unsigned ints, right?

I'll give various c# blowfish implementations a try but if none of them work I'll probably modify one.

Edit: Fixed it by using https://github.com/Mikeprod/Blowfish-compat in compat mode, thanks!