Alright,
This is what i found out about the Gom and Nodes by looking at the binary:
Many Gom functions can be found easy by looking in the string table for like "gom::createnode"
The Place where the strings are referenced is mostly some sort of Error logging.
The Base of the Gom is retrieved through a function "getGomBase" its located at swtor.exe + A8130
it can be found by searching for "Attempt to get GOM when none exists"
The Gom has a Pointer at Offset 654h to a Space with Pointers to some sort of Gom Entries.
These are stored by a Offset which is calculated by the Nodes ID.
The actual Offset of the Pointer is the Hash "Moduloed" by the value at Offset 658h.
Because of this I think that this value is the Gom Length or Max Length because there can be no bigger Offset than this value.
Those Gom Entrys look something like this:
Code:
GomEntry{
DWORD *Next (If two nodes are on the same Hash this points to the next one. This is derefferenced until "IdLow" and "IdHigh" matches the requested Id in "getGomEntryById" or a null pointer is reached)
DWORD Unknown
DWORD IdLow
DWORD IdHigh
DWORD Unknown (Has to be 1. Checked by getNodeById)
DWORD *Node (Returned by getNodeById on Success)
}
The *Node is a Pointer to the actual Node.
There exists a function which retrieves the Node Pointer from the Gom "getNodeById"
Its located at swtor.exe + B17A0. It gets 3 Arguments, Argument 1 is IdLow, 2 is IdHigh and the third one, well haven't figured it out yet.
When called the Base Address of the Gom is in the ecx Register, so i guess it's a thiscall on the Gom Class.
The function calls another one which i for now have called "getGomEntryById".
A List of those 3 Functions:
Code:
DWORD getGOMBase() (swtor.exe + A8130)
Returns the Base Address of the GOM
As of 1.2.0c (2012.04.20) the Base is stored in swtor.exe + 01091A2C
Code:
DWORD* PointerLoc getGomEntryByID(*DWORD ReturnAddresses) swtor.exe + B9060
esi == GomBase + 654h (Location of *NodeList)
eax == Pointer to the requested ID64
Retrieves a GomEntry from the GOM, which has its Hash as Offset
Return Addresses needs 2 DWORDS of Memory.
IDLow becomes the Address in the NodeList which Points to the Node
IDHigh becomes the Address of the Node
Returns a Pointer to the specified Argument "ReturnAddresses"
Code:
DWORD* Node getNodeById(DWORD IdLow, DWORD idHigh, DWORD Unknown) swtor.exe + B17A0
ecx = gomBase
Returns a Pointer to a Node in the Gom by its ID.
On Fail return 0
This is some Information about the Gom Itself:
Code:
GOM{
DWORD *GomClass1
// + 3BCh
DWORD *GomClass2
// + 654h
DWORD *NodeList
DWORD ModuloOffset (This may be the current / Max Length of the Gom since a Modulo with this never gets an offset above ModuloOffset)
DWORD Unknown
DWORD Unknown
DWORD NodeCount ???
DWORD Unknown
DWORD *NodeListFirst (The First used Address from *Nodelist)
DWORD NodeCount ???
}
Code:
GomClass1{
DWORD *VFTABLE
}
Code:
GomClass2{
DWORD *VFTABLE
}
Code:
GomClass2::VFTABLE{
DWORD *Unknown
DWORD *Unknown
DWORD *getNextFreeId() (called by createNode if no ID was specified. Constantly Counting up)
}
This is what the Node which is retrieved by getNodeById looks like. Most of this information is from the beginning of "gom::createnode" and i haven't managed to reverse this completely.
That's why most fields are marked to be 0 which is not necessarily true.
Code:
HeroNode{ (Size 58h)
0 DWORD *VFTABLE
4 DWORD Unknown <- Set to 0 on createNode
8 DWORD Unknown <- Set to 0 on createNode
C DWORD Unknown <- Set to 0A00h on createNode
10 DWORD Unknown <- Set to 0 on createNode
14
18 DWORD IdLow
1C DWORD IdHigh
20 DWORD Unknown <- Set to 0 on createNode
24 DWORD Unknown <- Set to 0 on createNode
28 DWORD Unknown <- Set to 0 on createNode
2C DWORD Unknown <- Set to 0 on createNode
30 DWORD gomBase
34 DWORD Unknown <- Set to 0 on createNode
38 DWORD Unknown <- Set to 0 on createNode
3C DWORD Unknown <- Set to 0 on createNode
40 DWORD Unknown <- Set to 0 on createNode
44 DWORD Unknown <- Set to 0 on createNode
48 DWORD Unknown <- Set to 0 on createNode
4C DWORD Unknown <- Set to 0 on createNode (Pointer to Fields?!?)
50 DWORD Unknown <- Set to 0 on createNode
54 DWORD Unknown <- Set to 8000h on createNode, Bit 6 == isReflecting
}
Code:
HeroNode::VFTABLE{
DWORD *GetPropertyOnNode
DWORD *SetPropertyOnNode
}
If you try to get the Node for your own Player Id you'll find a Pointer at 4Ch which Points to Memory where the Players Poistion and many other data is stored.
So a Node for the Player can be retrieved by getting the Gom Base.
Adding 654h to get the Base of the GomEntry List.
Calculate a Hash and the corresponding Offset.
Get the Gom Entry.
At Gom Entry + 14h you'll find a Pointer to the Node.
At Node + 4Ch is a Pointer to all of this Data like position etc.
This Data has at Offset 18h a Pointer which seems to be the Linked List for the "Mobs" which has been found earlier on this forum.
How to calculate the Hash for an Id has been described in another Post of luthien32. There he states mostly the same as above.
The function SetPropertyOnNode with the Players Node as this* gets called regularly during play with two String Parameters.
The first is "Render"
and the second "True"
And now guess what. Change True to false and your character doesn't get rendered. At least till the next function call.
Currently i'm trying to find more information about the Dom, but got the feeling that i'm running in circles.
That's why i have some Questions. Maybe someone of you has already found some of them out.
In the Hero Engine there are Classes and Nodes. Nodes are created from Classes. Just like Objects in C++.
So if I create a new Node I'll have to know how much Space I have to allocate for a specific class. This means I have to know where a class is "described".
This "describing" is done in the DOM. But where do i see something like a size of the class and Id's of Fields that belong to this Class.
Aditionaly there has to be some Place where Information is stored, which classes are already Glommed onto a Node. Something like a List of Ids.
Ok, that's what i have found out. I know it's not that much and maybe most of you already know everything above, but i thought i'll share my Information here.
And maybe get some answers to my Questions.