Ok, upon examination of the code section beginning at 004217B0 and ending with 00421834 I've found that it handles packets both with and without FLAG_COMBINED set.
Here's my annotated analysis of the code as I currently understand it:
Code:
; 04217b0 - begin of function that handles dispatching packets
.text:004217B0 sub_4217B0 proc near ; CODE XREF: sub_4217B0+46^Yp
.text:004217B0 ; sub_49A392+12A^Yp
.text:004217B0
.text:004217B0 var_ABC = dword ptr -0ABCh
.text:004217B0 var_AB8 = dword ptr -0AB8h
.text:004217B0 var_AB4 = dword ptr -0AB4h
.text:004217B0 var_AB0 = dword ptr -0AB0h
.text:004217B0 var_AAC = dword ptr -0AACh
.text:004217B0 var_AA8 = dword ptr -0AA8h
.text:004217B0 var_AA4 = dword ptr -0AA4h
.text:004217B0 var_AA0 = dword ptr -0AA0h
.text:004217B0
.text:004217B0 mov eax, offset loc_595CF3 ; begin packet handling
.text:004217B5 call sub_58087C
.text:004217BA sub esp, 0A90h
.text:004217C0 mov eax, [ebp+0Ch] ; retrieve opcode from stack
.text:004217C3 push ebx
.text:004217C4 test ah, 20h ; check if opcode is FLAG_COMBINED
.text:004217C7 mov [ebp-10h], ecx
.text:004217CA jz short loc_421818 ; if not FLAG_COMBINED then jump to opcode dispatch
.text:004217CC push dword ptr [ebp+14h]
.text:004217CF push dword ptr [ebp+10h]
.text:004217D2 push eax
.text:004217D3 lea eax, [ebp-40h]
.text:004217D6 push eax
.text:004217D7 call sub_4A3767 ; call to help unpack FLAG_COMBINED packets (uses implicit length table)
.text:004217DC add esp, 10h ; pop stack
.text:004217DF test al, al ; test for success / packet count?
.text:004217E1 jz short loc_421811 ; goto finished packet handling
.text:004217E3 xor ebx, ebx
.text:004217E5
.text:004217E5 loc_4217E5: ; CODE XREF: sub_4217B0+5F^Yj ; loop over sub-packets in FLAG_COMBINED packets
.text:004217E5 push dword ptr [ebp-38h]
.text:004217E8 mov ecx, [ebp-10h]
.text:004217EB movzx eax, word ptr [ebp-40h]
.text:004217EF push dword ptr [ebp-3Ch]
.text:004217F2 push eax
.text:004217F3 push dword ptr [ebp+8]
.text:004217F6 call sub_4217B0 ; call ourselves (packet handling)
.text:004217FB cmp dword_76FE88, ebx
.text:00421801 jz short loc_421811 ; goto finished packet handling
.text:00421803 lea eax, [ebp-40h]
.text:00421806 push eax
.text:00421807 call sub_4A38C0 ; anorther call to help unpack FLAG_COMBINED packets (uses implicit length table)
.text:0042180C test al, al ; test for success / packet count?
.text:0042180E pop ecx
.text:0042180F jnz short loc_4217E5 ; yes, loop around and handle next sub-packet
.text:00421811
.text:00421811 loc_421811: ; CODE XREF: sub_4217B0+31^Xj ; finished handling packet
.text:00421811 ; sub_4217B0+51^Xj
.text:00421811 mov al, 1
.text:00421813 jmp loc_424F25 ; jump to end of packet dispatch that will ret 0x10
.text:00421818 loc_421818: ; CODE XREF: sub_4217B0+1A^Xj ; Dispatch opcode function
.text:00421818 add eax, 0FFFFFFE9h ; subtract 27 from opcode
.text:0042181B xor ebx, ebx ; clear ebx
.text:0042181D push esi
.text:0042181E mov esi, [ebp+10h]
.text:00421821 cmp eax, 2BAh ; check that opcode is below 0x2ba
.text:00421826 push edi
.text:00421827 ja loc_423B3B ; jump to completed handling (function A6's address)
.text:0042182D movzx eax, ds:byte_4251D0[eax] ; get function code from byte in table
.text:00421834 jmp ds:off_424F34[eax*4] ; call packet function (base + (function code * 4))
I'm not sure why certain opcodes don't appear to be processed by this code. Tommorrow I may try brushing up on my WinDbg and try to set a breakpoint to trigger on one of these opcodes.
fester, how'd your analysis go?
Enjoy,
Zaphod (dohpaZ)