Page 2 of 3
Posted: Sun Oct 05, 2003 12:38 pm
by Amadeus
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 :)
Posted: Sun Oct 05, 2003 1:28 pm
by Amadeus
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 :)
Posted: Sun Oct 05, 2003 1:50 pm
by Lax
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
Posted: Sun Oct 05, 2003 4:08 pm
by onetimehero
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.
Posted: Sun Oct 05, 2003 5:12 pm
by Lax
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
Posted: Sun Oct 05, 2003 5:41 pm
by Amadeus
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.
Posted: Sun Oct 05, 2003 5:54 pm
by Lax
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.
Posted: Sun Oct 05, 2003 6:12 pm
by Amadeus
[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...
Posted: Sun Oct 05, 2003 6:43 pm
by Lax
EQPlayer is the same as MQ's _SPAWNINFO
/*0x18c*/ DWORD Anon;
[_SPAWNINFO+0x18c] == [EQPlayer+0x18c]
:)
Posted: Sun Oct 05, 2003 6:46 pm
by Lax
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...)
Posted: Sun Oct 05, 2003 8:10 pm
by Lax
I'll have an update to the 9-9-2003 solved offsets this week, fixed a bug or two and doing some minor improvements.
Posted: Sun Oct 05, 2003 10:26 pm
by Amadeus
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!!
Posted: Sun Oct 05, 2003 11:04 pm
by Amadeus
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?
Posted: Mon Oct 06, 2003 1:03 am
by Lax
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.
Posted: Mon Oct 06, 2003 1:09 am
by Amadeus
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