I've spent some time debugging and fucking around with packets (under bi.key, not bi2.key), and i think I've figured it out for the most part
WORD PacketSize = *( WORD* )( buf );
BYTE PacketType = *( BYTE* )( buf + 0x02 );
BYTE PacketID = *( BYTE* )( buf + 0x03 );
DWORD UnknownHash = *( DWORD* )( buf + 0x04 );
DWORD PBONumber = *( DWORD* )( buf + 0x08 );
DWORD PBOGroup = *( DWORD* )( buf + 0x0C );
DWORD UnknownFF = *( DWORD* )( buf + 0x10 );
DWORD PreviousPBONum = *( DWORD* )( buf + 0x14 );
After that it gets a little murky, but here, I'll try to explain
Here is a visual aid for some people
//[B4 01][00][A0][9E AC 1A CC][09 00 00 00][1B 00 00 00][FF FF FF 07][07 00 00 00][03 20][61 00 00 02][CE 01][72-character-hash][00][C7 01 03]
//[68 01][80][A0][9B AE 5F A3][0A 00 00 00][1B 00 00 00][FF FF FF 07][09 00 00 00][C7 01 20][61 00 00 03]
//[6C 01][80][A0][DD 65 E5 A3][10 00 00 00][1B 00 00 00][FF FF FF 07][0F 00 00 00][C7 01 20][61 00 00 03]
//[8B 01][00][A0][81 FB 44 01][73 00 00 00][22 00 00 00][FF FF FF FF][72 00 00 00][03 20][61 00 00 02][C7 01 03]
//[84 01][00][A0][2C 20 C8 F4][74 00 00 00][22 00 00 00][FF FF FF FF][73 00 00 00][03 20][61 00 00 03][C7 01 FC C2 02]
After the bytes with the [] it gets a little murky and unpredictable, as far as i can tell (but right after the end of each of these is a string containing the PBO name)
What i do know, however, is that after the string, which looks like
[PBO_NAME][00][BI KEY][OTHER KEY]
Now, the issue here is, the BI KEY can have different lengths.
#define BIKEY_SIZE 153
#define BI2KEY_SIZE BIKEY_SIZE + 1
If the start of [BI KEY] is 'bi' then it's a version 1 bikey, if the start of [BI KEY] is 'bi2' then it's a version 2 key, all you _really_ need to know about these is that the bi2 key contains one more byte (because it has one extra character, '2', in the header)
The bikey data, the first one anyway, is the actual key content from bi.key or bi2.key, depending on how it decides to roll.
The second key i assume is related to the PBO itself
There _can_ be some extra data after this key, but I've only seen that occur when unsigned pbos are passed through packets
I hope i was able to shed some light on how this entire process works, I'm hoping somebody can tell me what the bytes at the tail end of the packets above mean, or the UnknownFF area, but that wasn't really the purpose of this topic. Have fun with that!