[1.2.0c] Some Basic Info on the Gom and Nodes menu

User Tag List

Results 1 to 2 of 2
  1. #1
    Kamikaaze's Avatar Member
    Reputation
    13
    Join Date
    Apr 2007
    Posts
    10
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [1.2.0c] Some Basic Info on the Gom and Nodes

    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.
    Last edited by Kamikaaze; 04-20-2012 at 03:14 PM. Reason: Added Code Tags

    [1.2.0c] Some Basic Info on the Gom and Nodes
  2. #2
    Apoc's Avatar Angry Penguin
    Reputation
    1387
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/12
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Nice progress.

    First of all, the GOM is basically the struct that holds all the stuff required by the script execution engine. (Nodes, scripts, definitions, prototypes, associations, etc)

    Recently, HeroEngine added a few things to the GOM struct, which moved nodes and whatnot further down the GOM structure.

    The list of nodes is in fact a DomList (think of a hashmap, with some extra functionality)

    Code:
    struct DomList{
    void* List;
    DWORD MaxEntries;
    int pad8,padC;
    DWORD NumEntries;
    int pad14;
    void* First;
    int pad1C;
    };
    Most every node has a 64bit ID, which is looked up the "easy" way via the ID hash:
    Code:
    uint index = ((hidword ^ (lodword + (hidword << 6) + (hidword >> 2)))) % _nativeDomList.MaxEntries;
    Read by
    Code:
    _nativeDomList.List[index]
    From there you can pull any arbitrary node by ID from the list. (There is some extra processing required, since nodes can have linked neighbors, which may cause issues. I'll leave that up to you to find out!)

    HeroNode is in fact just a descendant of HeroVariableContainer.

    Code:
    struct HeroVariableContainer
    {
    void* VTable;
    void* NodePtr;
    void* TemplatePtr;
    DWORD Flags; // 0x10000 = deleted
    int pad10;
    }
    That should help you out some. And your "fields" pointer, is actually a pointer to a class that holds fields, methods, etc, for the scripting engine. (And replication. I'll leave it up to you to figure out more, again)

    As for your questions...

    In the Hero Engine there are Classes and Nodes. Nodes are created from Classes. Just like Objects in C++.
    Not at all. Nodes are in fact just object wrappers that contain a list of parents (since HeroEngine does "glomming" which allows for runtime inheritance, and whatnot), fields, and methods for a given object. These "classes" (more appropriately named "components") are defined in the DOM which you can pull from the .tor archives.

    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".
    Correct. And you'll need to know about the description for the class, or the HeroEngine script executive won't know what to do with it (and will crash the game). You'll need to create all the associated objects (NodeView, field/method holder class, definition, as well as the templates, etc, and any replication-based stuff).

    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.
    The GOM itself holds a list of definitions currently loaded. However, so does every node. I highly suggest checking the DOM loading code (really, just search for "loading definitions" or something along those lines)

    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.
    Every single node has a list of parent IDs (eg; which "classes" have been glommed onto the node). Keep searching, and you'll find it. (Hint: check where the field/methods are stored. Same structure holds parent IDs)

Similar Threads

  1. Some info about the binary, please
    By bingotheclowno in forum Wildstar Memory Editing
    Replies: 2
    Last Post: 06-24-2014, 01:10 PM
  2. Need info about the risks and some tips
    By Rubs90 in forum WoW Scams Help
    Replies: 12
    Last Post: 12-02-2008, 05:28 PM
  3. Some info on the new 25man(sunwell)
    By mkeg0dn in forum World of Warcraft General
    Replies: 0
    Last Post: 01-13-2008, 09:46 PM
  4. I need some better info for my computer upgrade.
    By Wheeze201 in forum Community Chat
    Replies: 0
    Last Post: 06-07-2007, 07:43 PM
  5. Any info on the hellfire citadel door exploit ?
    By arikaa in forum World of Warcraft Exploration
    Replies: 4
    Last Post: 06-02-2007, 04:54 PM
All times are GMT -5. The time now is 01:12 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search