§Information about how to find opcodes
... need to put more here, goal is to be a guide to the various techniques to finding opcodes...
§ASM String Refs
Opcodes which you can find because their call from Dispatch references a string which is at least somewhat unique (at the time of writting anyways). Hopefully only one of the references of the specified string will lead back to dispatch if traced upwards.
- OP_LevelUpdate - "%d of %d" and maybe "help\\tips\\"
- OP_LogoutReply - "****MSG_LOGOUT_PLAYER RECVD:DISCONNECTING (RECV_PKT)" or "Logout"
§ASM String ID Refs
Opcodes which can be found based on a call to to DisplayStringID
- OP_OpenTributeReply - 3379 "Tribute Master"
- Gotta trace it up into the general tribute opcode sub-dispatcher. Then figure out which opcode calls the routine which references the string ID.
- OP_ZoneUnavail - see Dev ASM Routines
- OP_FinishTrade - this is somewhat of a crappy way to find it, but it worked once. I just did a search for immediate value 0x236, then look through the results for a "cmp byte ptr [e*x+236h], 0". The one you are looking for should be in a rather short function, something that looks like the block below. Then cross-reference that back (should be immediate) to IncomingDispatch, and figure out the opcode:
text:004578EB sub_4578EB proc near
.text:004578EB mov ecx, dword_812DC0
.text:004578F1 cmp byte ptr [ecx+236h], 0 ; Compare Two Operands
.text:004578F8 jz short locret_4578FF ; Jump if Zero (ZF=1)
.text:004578FA jmp loc_555EE8 ; Jump
.text:004578FF locret_4578FF: ; CODE XREF: sub_4578EB+Dj
.text:004578FF retn ; Return Near from Procedure
.text:004578FF sub_4578EB endp
- OP_BecomeCorpse - This is even worse than above, but I will document it none the less. Go to IncomingDispatch and jump to the common second stage label (StartDispatchPhase2). You need to cross reference the call to the member function on SomeOtherMajorGlobalObject here.
.text:0045E116 mov ecx, SomeOtherMajorGlobalObject
Your looking for the code segment which calls this member function twice, in IDA its currently the only one with an address like: sub_4880FD:loc_48812D. Once you are there, you need to find an irregular call to the containing subroutine, by this I mean a jump into the sub instead of a call. You need to find the caller which looks something like this:
.text:0045E11C call sub_41A434 ; Call Procedure
.text:00452C66 mov eax, [esi+1A8h]
You should be able to xref the calling function directly back to incoming dispatch, then reverse out the opcode. However, there is another routine which does a similar jump, which also xrefs directly back to incoming dispatch, so you might have to check a couple.
.text:00452C6C fstp dword ptr [eax+48h] ; Store Real and Pop
.text:00452C6F jmp short loc_452C73 ; Jump
.text:00452C71 ; ---------------------------------------------------------------------------
.text:00452C71 loc_452C71: ; CODE XREF: sub_452BE0+84j
.text:00452C71 fstp st ; Store Real and Pop
.text:00452C73 loc_452C73: ; CODE XREF: sub_452BE0+8Fj
.text:00452C73 pop edi
.text:00452C74 mov ecx, esi
.text:00452C76 pop esi
.text:00452C77 pop ebp
.text:00452C78 jmp sub_4880FD ; Jump
- OP_InterruptCast: search for an immediate 0x108. find instances of "push 0x108" in the IncomingDispatch code segment. look for a fragment which looks like:
.text:0045E2E6 mov ecx, [ebp-110A4h]
Trace that back to its opcode
.text:0045E2EC push 1
.text:0045E2EE push 108h
.text:0045E2F3 add edi, 4 ; Add
.text:0045E2F6 push edi
Opcodes most easily found using packet collects of live.
- OP_SendTributes and OP_SendGuildTributes
- OP_SendGuildTributes and OP_SendTributes are 4 byte packets from client to server, seen only in collects which contain OP_TributeInfo and OP_GuildTributeInfo. Seen shortly after OP_CustomTitles.
§In Zone Actions
- OP_GetGuildsList - Sent when the client looks up a guild name for a guild (in OP_GuildsList) and gets an empty string. Contains just the client's name, null terminated.
Commands which produce an opcode from the client to the server. This should be a pretty complete list of commands, since it was gleaned from the EXE (around DoD
/agree - OP_Animation
/amaze - OP_Animation
/assist - OP_Assist
/attack - OP_AutoAttack
/find - OP_GMFind
/getguildmotd - OP_GetGuildMOTD
/goto - OP_GMGoto
/guilddelete - OP_GuildDelete
/guildinvite - OP_GuildInvite, reply on other side is OP_GuildInviteAccept
/guildleader - OP_GuildLeader
/guildmotd - OP_GuildMOTD
/guildpeace - OP_GuildPeace
/guildremove - OP_GuildRemove
/guildsay - OP_ChannelMessage I think...
/guildstatus - none
/guildwar - OP_GuildWar
/kick - OP_GMKick
/movelog - OP_MoveLog
/petition - OP_Petition
/report - 0x7f9d