Solved offsets for eqgame.exe 09-09-2003 import to IDA

A forum for feature requests/discussions and user submitted patches that improve MQ2

Moderator: MacroQuest Developers

Amadeus
The Maestro
The Maestro
Posts: 2036
Joined: Sat Jun 29, 2002 3:51 pm

Post by Amadeus » Sun Oct 05, 2003 12:38 pm

cooool ...I'm starting to get it ...Do any of you have a suggestion for a website that would just define the various commands ("mov", "cmp", "jz", etc...) for reference? ...or maybe that doesn't exist.

The best part about this explanation is that it put it in C++ terms ..which makes it oooooooh so much clearer than anything I've seen before.

I'm going to try doing what he did to another function in a little while and you guys will have to tell me if I did it right :)

Amadeus
The Maestro
The Maestro
Posts: 2036
Joined: Sat Jun 29, 2002 3:51 pm

Post by Amadeus » Sun Oct 05, 2003 1:28 pm

Here's an interesting question.

Code: Select all

.text:0045EFE5 EQPlayer__IsRoleplaying
.text:0045EFE5          ; EQPlayer__SetNameSpriteTint+150p ...
.text:0045EFE5                 mov     eax, [ecx+18Ch]
.text:0045EFEB                 shr     eax, 1
.text:0045EFED                 and     eax, 1
.text:0045EFF0                 retn
.text:0045EFF0 EQPlayer__IsRoleplaying endp
Obviously, 'ecx+18Ch' is 'this->Roleplaying'. Therefore, can I assume that 18Ch is always 'roleplying' throughout this entire stack? Or, will it vary from function to function? (ie, I could rename it in my version?..)



Also, here is my first attempt at distilling something down to C++ ....tell me how bad I do :)

Code: Select all

.text:0046137F EQPlayer__SetAfk
.text:0046137F 
.text:0046137F arg_0           = dword ptr  4
.text:0046137F 
.text:0046137F                 mov     eax, [esp+arg_0]
.text:00461383                 mov     [ecx+1BCh], eax
.text:00461389                 retn    4

Code: Select all

EQPlayer    EQPlayer::SetAfk(EQPlayer *player)
{
     player->afk = true;
     return player;
}
...oh well, probably all wrong, but worth a shot :)

Lax
We're not worthy!
We're not worthy!
Posts: 3524
Joined: Thu Oct 17, 2002 1:01 pm
Location: ISBoxer
Contact:

Post by Lax » Sun Oct 05, 2003 1:50 pm

Obviously, 'ecx+18Ch' is 'this->Roleplaying'. Therefore, can I assume that 18Ch is always 'roleplying' throughout this entire stack? Or, will it vary from function to function? (ie, I could rename it in my version?..)
[ecx+18Ch] will always correspond to this->Roleplaying (if it's correct here) when ecx is equal to EQPlayer or whatever it is set to before this function is called
Lax Lacks
Master of MQ2 Disaster
Purveyor of premium, EULA-safe MMORPG Multiboxing Software
* Multiboxing with ISBoxer: Quick Start Video
* EQPlayNice, WinEQ 2.0

onetimehero
a ghoul
a ghoul
Posts: 105
Joined: Fri Sep 05, 2003 2:42 pm

Post by onetimehero » Sun Oct 05, 2003 4:08 pm

Actually, it appears that the value at offset 0x18C is a bitflag. Notice the commands SHR and AND. It shifts the BITS in EAX right by one position, and then ANDs it with one. Comparative C++ code:

Code: Select all

return ((this->BitFlag >> 1) & 0x1);
And your AFK code:

Code: Select all

void EQPlayer::SetAfk(DWORD dwValue)
{ 
     this->afk = dwValue
     return; 
} 
remember, the This pointer is implied in C++, not explicitly passed.
Hmm. That's odd.

Lax
We're not worthy!
We're not worthy!
Posts: 3524
Joined: Thu Oct 17, 2002 1:01 pm
Location: ISBoxer
Contact:

Post by Lax » Sun Oct 05, 2003 5:12 pm

eq-comments.idc sent to eqmule, this puts the function declaration asa comment to all solved functions. works on any version of eqgame.exe as long as the function's offset has been named to the expected name in IDA
Lax Lacks
Master of MQ2 Disaster
Purveyor of premium, EULA-safe MMORPG Multiboxing Software
* Multiboxing with ISBoxer: Quick Start Video
* EQPlayNice, WinEQ 2.0

Amadeus
The Maestro
The Maestro
Posts: 2036
Joined: Sat Jun 29, 2002 3:51 pm

Post by Amadeus » Sun Oct 05, 2003 5:41 pm

How interesting ...so 'afk' is actually a bit flag rather than a boolean value. I suppose that makes sense in that they could always expand upon that to have different types of "afk"s.


I must also say that I would imagine that somewhere, someone at SOE is reading this thread and weeping.

Lax
We're not worthy!
We're not worthy!
Posts: 3524
Joined: Thu Oct 17, 2002 1:01 pm
Location: ISBoxer
Contact:

Post by Lax » Sun Oct 05, 2003 5:54 pm

on/off switches are typically a bit flag to save space :)

Also quick note, the current 9-9-2003 list has LocalPC incorrectly identified as g_SpellBookWnd, and LocalPC is somewhere completely off ;) I'll fix it soon.
Lax Lacks
Master of MQ2 Disaster
Purveyor of premium, EULA-safe MMORPG Multiboxing Software
* Multiboxing with ISBoxer: Quick Start Video
* EQPlayNice, WinEQ 2.0

Amadeus
The Maestro
The Maestro
Posts: 2036
Joined: Sat Jun 29, 2002 3:51 pm

Post by Amadeus » Sun Oct 05, 2003 6:12 pm

[ecx+18Ch] will always correspond to this->Roleplaying (if it's correct here) when ecx is equal to EQPlayer or whatever it is set to before this function is called
Is there a way to determine where "roleplaying" is in the struct based upon this information? 18Ch ...doesn't mean a lot to me really...

Lax
We're not worthy!
We're not worthy!
Posts: 3524
Joined: Thu Oct 17, 2002 1:01 pm
Location: ISBoxer
Contact:

Post by Lax » Sun Oct 05, 2003 6:43 pm

EQPlayer is the same as MQ's _SPAWNINFO
/*0x18c*/ DWORD Anon;

[_SPAWNINFO+0x18c] == [EQPlayer+0x18c]

:)
Lax Lacks
Master of MQ2 Disaster
Purveyor of premium, EULA-safe MMORPG Multiboxing Software
* Multiboxing with ISBoxer: Quick Start Video
* EQPlayNice, WinEQ 2.0

Lax
We're not worthy!
We're not worthy!
Posts: 3524
Joined: Thu Oct 17, 2002 1:01 pm
Location: ISBoxer
Contact:

Post by Lax » Sun Oct 05, 2003 6:46 pm

Note: Using the method just shown, you can identify other parts of the structure.

Code: Select all

.text:0045F4F1 EQPlayer__SetArmorType proc near        ; CODE XREF: UnPackNetPlayer+6Cp
.text:0045F4F1                                         ; EQPlayer__UpdateItemSlot+262p ...
.text:0045F4F1 
.text:0045F4F1 arg_0           = dword ptr  4
.text:0045F4F1 arg_4           = dword ptr  8
.text:0045F4F1 
.text:0045F4F1                 mov     eax, [esp+arg_0] ; public: void __thiscall EQPlayer::SetArmorType(int,int)
.text:0045F4F5                 test    eax, eax
.text:0045F4F7                 jl      short locret_45F509
.text:0045F4F9                 cmp     eax, 8
.text:0045F4FC                 jg      short locret_45F509
.text:0045F4FE                 mov     edx, [esp+arg_4]
.text:0045F502                 mov     [ecx+eax*4+0F0h], edx
.text:0045F509 
.text:0045F509 locret_45F509:                          ; CODE XREF: EQPlayer__SetArmorType+6j
.text:0045F509                                         ; EQPlayer__SetArmorType+Bj
.text:0045F509                 retn    8
.text:0045F509 EQPlayer__SetArmorType endp
[ecx+eax*4+0F0h] <-- .. the eax*4 picks a spot in an array, ecx+0x0F0 is the spot in the struct. Obviously this shows that _SPAWNINFO+0x0F0 is equipment type array. (I posted the addition in the Structs board some time ago, but it never got put in CVS...)
Lax Lacks
Master of MQ2 Disaster
Purveyor of premium, EULA-safe MMORPG Multiboxing Software
* Multiboxing with ISBoxer: Quick Start Video
* EQPlayNice, WinEQ 2.0

Lax
We're not worthy!
We're not worthy!
Posts: 3524
Joined: Thu Oct 17, 2002 1:01 pm
Location: ISBoxer
Contact:

Post by Lax » Sun Oct 05, 2003 8:10 pm

I'll have an update to the 9-9-2003 solved offsets this week, fixed a bug or two and doing some minor improvements.
Lax Lacks
Master of MQ2 Disaster
Purveyor of premium, EULA-safe MMORPG Multiboxing Software
* Multiboxing with ISBoxer: Quick Start Video
* EQPlayNice, WinEQ 2.0

Amadeus
The Maestro
The Maestro
Posts: 2036
Joined: Sat Jun 29, 2002 3:51 pm

Post by Amadeus » Sun Oct 05, 2003 10:26 pm

Lax,

That correlation between the functions there and the structs that you just mentioned makes me oh so very happy. Now I should be able to fill in some of the struct values that have driven me crazy for so long!!

Amadeus
The Maestro
The Maestro
Posts: 2036
Joined: Sat Jun 29, 2002 3:51 pm

Post by Amadeus » Sun Oct 05, 2003 11:04 pm

hmmm...ok Lax, explain this please

Code: Select all

.text:0046137F EQPlayer__SetAfk 
.text:0046137F 
.text:0046137F arg_0           = dword ptr  4 
.text:0046137F 
.text:0046137F                 mov     eax, [esp+arg_0] 
.text:00461383                 mov     [ecx+1BCh], eax 
.text:00461389                 retn    4 
According to what you said, then ecx+1BCh should be _SPAWNINFO+0x1bc....

But...according to our spawn info, it should be 0x194 for AFK ...right?

Lax
We're not worthy!
We're not worthy!
Posts: 3524
Joined: Thu Oct 17, 2002 1:01 pm
Location: ISBoxer
Contact:

Post by Lax » Mon Oct 06, 2003 1:03 am

Two things

A) The function could have been misidentified (some are)
B) The MQ structs often include guesses or remnants of old structs before they were changed in a new EQ version.

In this case, the function was misidentified AND the real EQPLAYER__SetAfk uses 0x154 (so the MQ info is wrong)

I'll find the problem that caused this misidentification and fix it before uploading the new list in a day or two.

Misidentification will happen most often with very small functions, so be careful of trusting the smaller ones just yet :) Also, as this type of bug gets fixed in my program, more offsets will be identified.
Lax Lacks
Master of MQ2 Disaster
Purveyor of premium, EULA-safe MMORPG Multiboxing Software
* Multiboxing with ISBoxer: Quick Start Video
* EQPlayNice, WinEQ 2.0

Amadeus
The Maestro
The Maestro
Posts: 2036
Joined: Sat Jun 29, 2002 3:51 pm

Post by Amadeus » Mon Oct 06, 2003 1:09 am

Ok cool ..I'll wait for hte next big upgrade to the IDC before working any more ...but I'd love to be able to find parts of the struct that are missing and then just do a search for ecx+whatever to find them to help guess what some of that funky data is int he structs that we don't know yet!!!!!

Amadeus, the structmeister