Thread: Spirit Shrouds
View Single Post
  #5  
Old 10-04-2009, 11:15 PM
Pend
Fire Beetle
 
Join Date: Sep 2009
Posts: 16
Default

OP_ShroudUnknown3=0x1573

This one has been most problematic to reverse engineer. It's almost as if the server needs to be directly aware of some object pointer offsets found in eqgame.exe. One thing I found by investigating this was that the value of UniqueID in the above Opcodes cannot be random.

Code:
.text:004FF9C9 sub_4FF9C9 proc near                    ; CODE XREF: sub_4244BA+Ap
.text:004FF9C9                                         ; sub_42EC50+Dp ...
.text:004FF9C9
.text:004FF9C9 arg_0= dword ptr  8
.text:004FF9C9
.text:004FF9C9 push    esi
.text:004FF9CA mov     esi, [esp+arg_0]
.text:004FF9CE mov     eax, esi
.text:004FF9D0 xor     edx, edx
.text:004FF9D2 div     dword ptr [ecx+4]
.text:004FF9D5 mov     eax, [ecx]
.text:004FF9D7 mov     eax, [eax+edx*4]
.text:004FF9DA jmp     short loc_4FF9E4
.text:004FF9DC ; ---------------------------------------------------------------------------
.text:004FF9DC
.text:004FF9DC loc_4FF9DC:                             ; CODE XREF: sub_4FF9C9+1Dj
.text:004FF9DC cmp     [eax+4], esi
.text:004FF9DF jz      short loc_4FF9E8
.text:004FF9E1 mov     eax, [eax+8]
.text:004FF9E4
.text:004FF9E4 loc_4FF9E4:                             ; CODE XREF: sub_4FF9C9+11j
.text:004FF9E4 test    eax, eax
.text:004FF9E6 jnz     short loc_4FF9DC
.text:004FF9E8
.text:004FF9E8 loc_4FF9E8:                             ; CODE XREF: sub_4FF9C9+16j
.text:004FF9E8 pop     esi
.text:004FF9E9 retn    4
.text:004FF9E9 sub_4FF9C9 endp
This subroutine gets used frequently. For the opcode in question, the instruction at 004FF9D2 is problematic:
div dword ptr [ecx+4]

This essentially takes our UniqueID, divides it by 0x17 and only uses the remainder. (UniqueID % 23) It then multiplies by 4 (it's probably doing pointer math), and offsets a pointer by that amount and grabs the value at that new location:
.text:004FF9D7 mov eax, [eax+edx*4]

That value must be non-zero:
.text:004FF9E4 test eax, eax
.text:004FF9E6 jnz short loc_4FF9DC

Then, we assume that value is yet another pointer and compare the second uint32 at the pointer's destination with our original UniqueID:
.text:004FF9DC cmp [eax+4], esi

If we don't find it, we increment our pointer by two unit32s and try the loop back to the non-zero check and do it again.
.text:004FF9DF jz short loc_4FF9E8
.text:004FF9E1 mov eax, [eax+8]

All of this means that the UniqueID is much more than just a UniqueID. It's also an offset for a pointer that expects to find the same offset value somewhere in a structure at its destination.

Its giving me a headache.

Now, I did find only one such possible UniqueID that would satisfy this algorithm. The problem is, that UniqueID was 0x8800001F. As mentioned in a prior post, this value makes an invalid UniqueID because this is < 0 and becomes 0x77FFFFE1 before being saved by the client. :(

Best I can tell, my real problem may be that something hasn't yet been set in the object I'm referencing here. (Faced similar problems getting the other opcodes to work--if the shroud selection window weren't open when the opcode was sent, a subroutine would return a 0 result because an object lookup would fail.)

At this time, I'm not sure what else I need to send to get that object reference to be valid.

Alas, I'll keep hacking away at it.

One last note about this one: the contents of the packet aren't even referenced by this point, but this subroutine's failure cascades into the entire packet being discarded. The UniqueID in this problem is referring to the UniqueID of the currently highlighted template in the shroud selection window. The window must be open for this opcode to even get this far, however. Of that I am certain. So, too, am I certain that OP_ShroudUnknown1=0x6d32 is also handled by this window.
Reply With Quote