[mac][3.3.2] Client DB - Out of Process Reading menu

Shout-Out

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 15 of 19
  1. #1
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [mac][3.3.2] Client DB - Out of Process Reading

    So I've been trying to understand the structure of rows from:

    http://www.mmowned.com/forums/wow-me...c-reading.html (and from WOWX source)

    I was able to find the ClientDb_RegisterBase (0x0018A060) function for mac (which, is a bit more of a challenge to pull each individual offset out of, the assembly is a bit different). But I easily enough found the Spell DB ptr at 0xD87980.

    I'm very much struggling w/actually getting row information from this database. Is there more documentation somewhere that I can better understand?

    I was even just jumping around in my memory viewer to try to make sense of the data, but I don't see any pattern to the information displayed.

    You can see how far I am here (not very):
    tanaris4 private pastebin - collaborative debugging tool

    Any help is greatly appreciated! Going to take a look at GetLocalizedRow and see if that will help me any, although I have a feeling I'll still be confused.

    Thanks!

    Edit: Ideally I'm trying to read spell names (and eventually items) by the spell ID, I'm assuming this is possible using this method, please correct me if I'm wrong
    Last edited by Tanaris4; 02-18-2010 at 10:06 PM.
    https://tanaris4.com

    [mac][3.3.2] Client DB - Out of Process Reading
  2. #2
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Anyone have any ideas here? I'm really struggling w/how the client database is organized. I'm basically just jumping around trying to find a pattern.

    Seems like some addresses land on a spell ID (generally those where &0x1 is true), and then the spell name ptr is some distance away from the ID, varies from some being 0x70 away, and some being 0x40 away, I am really struggling with making sense of this.

    Reversing hasn't really gotten me anywhere, been trying to use this (which I believe dumps the auras - along w/other random information):

    tanaris4 private pastebin - collaborative debugging tool (0xD87980 is the spell pointer).

    So I'm reversing this segment:
    Code:
    #
            v69 = 0;
    #
                v66 = v21 + 3132;
    #
                v35 = *(_DWORD *)(v21 + 3516);
    #
                if ( v35 == -1 )
    #
                  goto LABEL_61;
    #
                while ( v68 < v35 )
    #
                {
    #
                  if ( *(_DWORD *)(v66 + 384) == -1 )
    #
                    v39 = *(_DWORD *)(v66 + 8) + v69;
    #
                  else
    #
                    v39 = v66 + v69;
    #
                  v40 = *(_DWORD *)(v39 + 8);
    #
                  if ( v40 )
    #
                  {
    #
                    v41 = *(&dword_D87980 + 4);
    #
                    if ( v40 >= v41
    #
                      && v40 <= *(&dword_D87980 + 3)
    #
                      && (v42 = *(const void **)(*(&dword_D87980 + 8) + 4 * (v40 - v41))) != 0 )
    #
                    {
    Which got me to:
    Code:
    typedef struct WoWClientDb {
        UInt32    _vtable;		// 0x0
        UInt32  isLoaded;		// 0x4
        UInt32  numRows;		// 0x8
        UInt32  maxIndex;		// 0xC
        UInt32  minIndex;		// 0x10
    	UInt32  stringTablePtr;	// 0x14
    	UInt32 _vtable2;		// 0x18
    	// array of row pointers after this...
    	UInt32 row1;			// 0x1C
    	UInt32 row2;			// 0x20
    	UInt32 row3;			// 0x24
    	UInt32 row4;			// 0x28
    	
    } WoWClientDb;
    
    - (IBAction)test: (id)sender{
    	
    	MemoryAccess *memory = [controller wowMemoryAccess];
    	UInt32 spellPtr = 0xD87980;
    	
    	WoWClientDb db;
    	[memory loadDataForObject: self atAddress: spellPtr Buffer:(Byte*)&db BufLength: sizeof(db)];
    	
    	if ( db.stringTablePtr ){
    		
    		UInt32 addressOfString = db.row2 + ( 4 * ( 39347 - db.minIndex ) );
    I'm using 39347 here, basically thinking this is a spell ID (but now realizing it's just an index in the row, but I don't know how to always "hit" an actual spell)

    Any ideas?
    Last edited by Tanaris4; 02-19-2010 at 03:06 PM.
    https://tanaris4.com

  3. #3
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry to be annoying here, but I'm willing to offer some donation funds if someone w/the knowledge would be willing to help. I hate that my bot currently pulls data from wowhead and would LOVE to get access to this database.

    Thanks in advance
    https://tanaris4.com

  4. #4
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Most DBCs follow their file structure almost exactly. (Some aren't quite the same, but it's easy enough to figure out)

    CategoryBC - WoW.Dev Wiki are the file structures. (They're the same on Macs IIRC)

    Also the structure for the DBCs in memory is as follows;

    Code:
    struct WoWClientDB
    {
      void *funcTable;
      int isLoaded;
      int numRows;
      int maxIndex;
      int minIndex;
      int stringTable;
      void *funcTable2;
      int FirstRow;
      DWORD **Rows;
    };
    Rows is just an array of pointers to a DBC row.

    The way to access the specific row you're looking for; *should* be the same as on Windows, however it may be a bit different.

    I suggest dereferencing the pointer into a struct to make it easier.

    A thing to note about DBCs in game: anywhere you see a 'localized' string, gets turned into a single char* string. (So your 7 localized strings, turns into the char* that is localized to the clients language.)

    Yea, that's pretty much all I can say about it.

  5. #5
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Apoc-

    Thanks for the post, great link as well - definitely needed that to understand the structure. Can you give more insight into the row traversal? That is where I'm struggling. I can randomly get to a struct that is the link you showed, but I can't do this consistently.

    Thanks!
    https://tanaris4.com

  6. #6
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Obviously you know I can't do it in Obj-C (no sane person uses that language, unless you're on Mac. *cough*)

    Here's the code in C#/C++ though;

    C#:

    Code:
    public Row GetRow(int index)
                {
                    if (index >= MinIndex && index <= MaxIndex)
                    {
                        return new Row(Memory.Read<IntPtr>((IntPtr) (_nativeDb.Rows.ToInt64() + ((index - MinIndex) * 4))));
                    }
                    return new Row(IntPtr.Zero);
    }[/code]

    C++:
    Code:
    Row* GetRow(WoWClientDB *db, int index)
    {
    	if (index >= db->MinIndex && index <= db->MaxIndex)
    	{
    		return reinterpret_cast<Row*>(db->Rows[index - db->MinIndex]);
    	}
    	return NULL:
    }
    It's not too difficult. If the index doesn't 'exist' (meaning there's no entry for it, but it lies within the min/max) you'll basically just get a 0 filled return. (WoW fills the entire array, but with zeroed out indexes for 'missing' rows).

  7. #7
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yea I saw that in your original post but still didn't understand the traversal. If you hit 0, yes, you ignore it. But sometimes I would hit rows that don't start w/the spell ID (referenced structure for spells in your link). So I may have implemented it wrong.

    Why are you reading the row ptr as 64-bit?
    Code:
    _nativeDb.Rows.ToInt64()
    Wouldn't I just do
    Code:
    int rowPtr = Rows[0] + ((index - MinIndex) * 4));
    Bit confused on the purpose of the Rows pointer in the original struct

    Thanks again, sorry i'm half retarded
    https://tanaris4.com

  8. #8
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Tanaris4 View Post
    Yea I saw that in your original post but still didn't understand the traversal. If you hit 0, yes, you ignore it. But sometimes I would hit rows that don't start w/the spell ID (referenced structure for spells in your link). So I may have implemented it wrong.

    Why are you reading the row ptr as 64-bit?
    Code:
    _nativeDb.Rows.ToInt64()
    Wouldn't I just do
    Code:
    int rowPtr = Rows[0] + ((index - MinIndex) * 4));
    Bit confused on the purpose of the Rows pointer in the original struct

    Thanks again, sorry i'm half retarded
    I wasn't reading it as a 64bit value. I was simply 'changing' it to one, in order to add to it. (It's a drawback of how IntPtr works. It's quite a pain in the ass.)
    Last edited by Apoc; 02-23-2010 at 09:57 PM.

  9. #9
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Perfect thanks! Hopefully will post back w/my implementation (for the maybe 1 other person that even cares about macs ) soon
    https://tanaris4.com

  10. #10
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Apoc-

    Was finally able to read them all! I just wasn't going further enough down the list. I added an additional check to make sure the SpellID was < maxIndex (probably not a good idea, it should prob. be < max spell ID in the game, which may be the same). Code here: tanaris4 private pastebin - collaborative debugging tool

    My question - how out of date is the link you posted? I'm noticing the structs that are pointed to in my spell list are about 0x90 long (and Spell.dbc - WoW.Dev Wiki is HUGE). And the data doesn't look consistent, see (0x0 is obv. spell ID):



    Has anyone actually used the ClientDB to traverse spell info? Anyone know the structure?
    https://tanaris4.com

  11. #11
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It's so strange, I'm able to traverse the entire list, but I can't make sense of any of the data. Been trying to find the pointer to the spell name for like 2 hours now And it's always some offset away from the string pointer in the original struct (db.stringTablePtr), but I can't determine how each row actually points to this string.

    Any ideas?
    https://tanaris4.com

  12. #12
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
        [StructLayout(LayoutKind.Sequential)]
        internal struct Flag96
        {
            public uint DwA;
            public uint DwB;
            public uint DwC;
    
            public override string ToString()
            {
                return string.Format("DwA: {0} - DwB: {1} - DwC: {2}", DwA, DwB, DwC);
            }
        }
    
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        internal struct SpellEntry
        {
            public uint Id;
            public uint Category;
            public uint Dispel;
            public uint Mechanic;
            public uint Attributes;
            public uint AttributesEx;
            public uint AttributesEx2;
            public uint AttributesEx3;
            public uint AttributesEx4;
            public uint AttributesEx5;
            public uint AttributesEx6;
            public uint AttributesEx7;
            public uint Stances;
            public uint unk_320_2;
            public uint StancesNot;
            public uint unk_320_3;
            public uint Targets;
            public uint TargetCreatureType;
            public uint RequiresSpellFocus;
            public uint FacingCasterFlags;
            public uint CasterAuraState;
            public uint TargetAuraState;
            public uint CasterAuraStateNot;
            public uint TargetAuraStateNot;
            public uint casterAuraSpell;
            public uint targetAuraSpell;
            public uint excludeCasterAuraSpell;
            public uint excludeTargetAuraSpell;
            public uint CastingTimeIndex;
            public uint RecoveryTime;
            public uint CategoryRecoveryTime;
            public uint InterruptFlags;
            public uint AuraInterruptFlags;
            public uint ChannelInterruptFlags;
            public uint procFlags;
            public uint procChance;
            public uint procCharges;
            public uint maxLevel;
            public uint baseLevel;
            public uint spellLevel;
            public uint DurationIndex;
            public uint powerType;
            public uint manaCost;
            public uint manaCostPerlevel;
            public uint manaPerSecond;
            public uint manaPerSecondPerLevel;
            public uint rangeIndex;
            public float speed;
            public uint modalNextSpell;
            public uint StackAmount;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2, ArraySubType = UnmanagedType.U4)]
            public uint[] Totem;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.I4)]
            public int[] Reagent;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.U4)]
            public uint[] ReagentCount;
            public int EquippedItemClass;
            public int EquippedItemSubClassMask;
            public int EquippedItemInventoryTypeMask;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.U4)]
            public uint[] Effect;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.I4)]
            public int[] EffectDieSides;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.I4)]
            public int[] EffectBaseDice;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.R4)]
            public float[] EffectDicePerLevel;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.R4)]
            public float[] EffectRealPointsPerLevel;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.I4)]
            public int[] EffectBasePoints;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.U4)]
            public uint[] EffectMechanic;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.U4)]
            public uint[] EffectImplicitTargetA;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.U4)]
            public uint[] EffectImplicitTargetB;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.U4)]
            public uint[] EffectRadiusIndex;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.U4)]
            public uint[] EffectApplyAuraName;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.U4)]
            public uint[] EffectAmplitude;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.R4)]
            public float[] EffectMultipleValue;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.U4)]
            public uint[] EffectChainTarget;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.U4)]
            public uint[] EffectItemType;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.I4)]
            public int[] EffectMiscValue;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.I4)]
            public int[] EffectMiscValueB;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.U4)]
            public uint[] EffectTriggerSpell;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.R4)]
            public float[] EffectPointsPerComboPoint;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.Struct)]
            public Flag96[] EffectSpellClassMask;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2, ArraySubType = UnmanagedType.U4)]
            public uint[] SpellVisual;
            public uint SpellIconID;
            public uint activeIconID;
            public uint spellPriority;
            [MarshalAs(UnmanagedType.LPStr)]
            public string SpellName;
            [MarshalAs(UnmanagedType.LPStr)]
            public string Rank;
            [MarshalAs(UnmanagedType.LPStr)]
            public string Description;
            [MarshalAs(UnmanagedType.LPStr)]
            public string ToolTip;
            public uint ManaCostPercentage;
            public uint StartRecoveryCategory;
            public uint StartRecoveryTime;
            public uint MaxTargetLevel;
            public uint SpellFamilyName;
            public Flag96 SpellFamilyFlags;
            public uint MaxAffectedTargets;
            public uint DmgClass;
            public uint PreventionType;
            public uint StanceBarOrder;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.R4)]
            public float[] DmgMultiplier;
            public uint MinFactionId;
            public uint MinReputation;
            public uint RequiredAuraVision;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2, ArraySubType = UnmanagedType.U4)]
            public uint[] TotemCategory;
            public int AreaGroupId;
            public int SchoolMask;
            public uint runeCostID;
            public uint spellMissileID;
            public uint PowerDisplayId;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.R4)]
            public float[] unk_320_4;
            public uint spellDescriptionVariableID;
    
            public override string ToString()
            {
                return
                    string.Format(
                        "ID: {0}, Category: {1}, Dispel: {2}, Mechanic: {3}, Attributes: {4}, AttributesEx: {5}, AttributesEx2: {6}, AttributesEx3: {7}, AttributesEx4: {8}, AttributesEx5: {9}, AttributesEx6: {10}, AttributesEx7: {11}, Stances: {12}, Unk3202: {13}, StancesNot: {14}, Unk3203: {15}, Targets: {16}, TargetCreatureType: {17}, RequiresSpellFocus: {18}, FacingCasterFlags: {19}, CasterAuraState: {20}, TargetAuraState: {21}, CasterAuraStateNot: {22}, TargetAuraStateNot: {23}, CasterAuraSpell: {24}, TargetAuraSpell: {25}, ExcludeCasterAuraSpell: {26}, ExcludeTargetAuraSpell: {27}, CastingTimeIndex: {28}, RecoveryTime: {29}, CategoryRecoveryTime: {30}, InterruptFlags: {31}, AuraInterruptFlags: {32}, ChannelInterruptFlags: {33}, ProcFlags: {34}, ProcChance: {35}, ProcCharges: {36}, MaxLevel: {37}, BaseLevel: {38}, SpellLevel: {39}, DurationIndex: {40}, PowerType: {41}, ManaCost: {42}, ManaCostPerlevel: {43}, ManaPerSecond: {44}, ManaPerSecondPerLevel: {45}, RangeIndex: {46}, Speed: {47}, ModalNextSpell: {48}, StackAmount: {49}, Totem: {50}, Reagent: {51}, ReagentCount: {52}, EquippedItemClass: {53}, EquippedItemSubClassMask: {54}, EquippedItemInventoryTypeMask: {55}, Effect: {56}, EffectDieSides: {57}, EffectBaseDice: {58}, EffectDicePerLevel: {59}, EffectRealPointsPerLevel: {60}, EffectBasePoints: {61}, EffectMechanic: {62}, EffectImplicitTargetA: {63}, EffectImplicitTargetB: {64}, EffectRadiusIndex: {65}, EffectApplyAuraName: {66}, EffectAmplitude: {67}, EffectMultipleValue: {68}, EffectChainTarget: {69}, EffectItemType: {70}, EffectMiscValue: {71}, EffectMiscValueB: {72}, EffectTriggerSpell: {73}, EffectPointsPerComboPoint: {74}, EffectSpellClassMask: {75}, SpellVisual: {76}, SpellIconID: {77}, ActiveIconID: {78}, SpellPriority: {79}, SpellName: {80}, Rank: {81}, Description: {82}, ToolTip: {83}, ManaCostPercentage: {84}, StartRecoveryCategory: {85}, StartRecoveryTime: {86}, MaxTargetLevel: {87}, SpellFamilyName: {88}, SpellFamilyFlags: {89}, MaxAffectedTargets: {90}, DmgClass: {91}, PreventionType: {92}, StanceBarOrder: {93}, DmgMultiplier: {94}, MinFactionID: {95}, MinReputation: {96}, RequiredAuraVision: {97}, TotemCategory: {98}, AreaGroupID: {99}, SchoolMask: {100}, RuneCostID: {101}, SpellMissileID: {102}, PowerDisplayID: {103}, Unk3204: {104}, SpellDescriptionVariableID: {105}",
                        Id, Category, Dispel, Mechanic, Attributes, AttributesEx, AttributesEx2, AttributesEx3, AttributesEx4,
                        AttributesEx5, AttributesEx6, AttributesEx7, Stances, unk_320_2, StancesNot, unk_320_3, Targets, TargetCreatureType,
                        RequiresSpellFocus, FacingCasterFlags, CasterAuraState, TargetAuraState, CasterAuraStateNot, TargetAuraStateNot,
                        casterAuraSpell, targetAuraSpell, excludeCasterAuraSpell, excludeTargetAuraSpell, CastingTimeIndex, RecoveryTime,
                        CategoryRecoveryTime, InterruptFlags, AuraInterruptFlags, ChannelInterruptFlags, procFlags, procChance, procCharges,
                        maxLevel, baseLevel, spellLevel, DurationIndex, powerType, manaCost, manaCostPerlevel, manaPerSecond,
                        manaPerSecondPerLevel, rangeIndex, speed, modalNextSpell, StackAmount, Totem.ToRealString(), Reagent.ToRealString(), ReagentCount.ToRealString(),
                        EquippedItemClass, EquippedItemSubClassMask, EquippedItemInventoryTypeMask, Effect.ToRealString(), EffectDieSides.ToRealString(), EffectBaseDice.ToRealString(),
                        EffectDicePerLevel.ToRealString(), EffectRealPointsPerLevel.ToRealString(), EffectBasePoints.ToRealString(), EffectMechanic.ToRealString(), EffectImplicitTargetA.ToRealString(),
                        EffectImplicitTargetB.ToRealString(), EffectRadiusIndex.ToRealString(), EffectApplyAuraName.ToRealString(), EffectAmplitude.ToRealString(), EffectMultipleValue.ToRealString(),
                        EffectChainTarget.ToRealString(), EffectItemType.ToRealString(), EffectMiscValue.ToRealString(), EffectMiscValueB.ToRealString(), EffectTriggerSpell.ToRealString(), EffectPointsPerComboPoint.ToRealString(),
                        EffectSpellClassMask.ToRealString(), SpellVisual.ToRealString(), SpellIconID, activeIconID, spellPriority, SpellName, Rank, Description, ToolTip,
                        ManaCostPercentage, StartRecoveryCategory, StartRecoveryTime, MaxTargetLevel, SpellFamilyName, SpellFamilyFlags,
                        MaxAffectedTargets, DmgClass, PreventionType, StanceBarOrder, DmgMultiplier.ToRealString(), MinFactionId, MinReputation,
                        RequiredAuraVision, TotemCategory.ToRealString(), AreaGroupId, SchoolMask, runeCostID, spellMissileID, PowerDisplayId, unk_320_4.ToRealString(),
                        spellDescriptionVariableID);
            }
        }
    That should help ya.

  13. #13
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Check out my screenshots above though, the actual size is 0x90, so for some reason the Spell entry I'm viewing doesn't follow what you just posted or what's on the wiki (or I'm doing something wrong).

    I actually found the function that references Spell.dbc, then hooked it + printed out the offset it prints, so I know for a fact I'm referencing the correct DB pointer for the SpellEntry DB.

    The only thing that holds is:
    Code:
    public uint Id;
    https://tanaris4.com

  14. #14
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ahh right, with Spell.dbc you need to -0x18 from the pointer to start grabbing rows.

    Don't ask.

    Code:
                public Row GetLocalizedRow(int index)
                {
                    if (_getLocalizedRow == null)
                    {
                        _getLocalizedRow =
                            Utilities.RegisterDelegate<ClientDbGetLocalizedRow>(
                                (uint) GlobalOffsets.ClientDb_GetLocalizedRow);
                    }
                    IntPtr rowPtr = Marshal.AllocHGlobal(704);
                    int tmp = _getLocalizedRow(new IntPtr(Address.ToInt32() - 0x18), index, rowPtr);
                    if (tmp != 0)
                    {
                        return new Row(rowPtr, true);
                    }
                    Marshal.FreeHGlobal(rowPtr);
                    return null;
                }
    The only time GetLocalizedRow is used, is for Spell.dbc. (All it does, is push the row into a buffer. There's no real need for it, it just reminds me that 'extra' work is being done.)

    Also note the size being allocated. (704 bytes) That's the total size of the SpellEntry struct.

  15. #15
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    from which pointer? From the original Rows pointer? (firstRow)

    Moving back 0x18 doesn't really make much of a difference, in fact, the structs I get aren't even correct (i.e. I'm not landing on the spell ID anymore), and still are roughly 0x90 ( *4) in size

    Edit: Latest source, which address am I subtracting 0x18 from? I tried both that I read, and no success:

    Code:
    	// hooked the spell function which was passed: 0xD87980 0xA8D268 0x194
    	UInt32 spellPtr = 0xD87980;//;
    	
    	WoWClientDb db;
    	[memory loadDataForObject: self atAddress: spellPtr Buffer:(Byte*)&db BufLength: sizeof(db)];
    	
    	if ( db.stringTablePtr ){
    		int index;
    		for ( index = 0; index < db.numRows; index++ ){
    			
    			UInt32 rowPtr = db.row2 + ( 4 * ( index - db.minIndex ) );
    			UInt32 addressOfSpellStruct = 0x0;
    			[memory loadDataForObject: self atAddress: rowPtr Buffer:(Byte*)&addressOfSpellStruct BufLength: sizeof(addressOfSpellStruct)];
    			
    			if ( addressOfSpellStruct ){
    			
    				UInt32 tmp = 0x0;
    				[memory loadDataForObject: self atAddress: addressOfSpellStruct Buffer:(Byte*)&tmp BufLength: sizeof(tmp)];
    			
    				// valid spell ID
    				if ( tmp <= db.maxIndex ){
    					PGLog(@"[%d:0x%X]  %d", index, addressOfSpellStruct, tmp);
    				}
    			}
    		}
    }
    Last edited by Tanaris4; 02-26-2010 at 07:36 PM.
    https://tanaris4.com

Page 1 of 2 12 LastLast

Similar Threads

  1. Marshalling data out of process...
    By Sillyboy72 in forum WoW Memory Editing
    Replies: 3
    Last Post: 01-23-2009, 09:06 PM
  2. [C++]CSyringe - Out of Process Mem Manager
    By cenron in forum WoW Memory Editing
    Replies: 1
    Last Post: 01-21-2009, 08:48 PM
  3. [Out of Process] GetNumLootItems()
    By hypnodok in forum WoW Memory Editing
    Replies: 8
    Last Post: 12-16-2008, 02:51 PM
  4. [Help] Accessing a function Out of Process
    By cenron in forum WoW Memory Editing
    Replies: 18
    Last Post: 10-14-2008, 05:49 AM
  5. Can you read player names out of process?
    By sweeper18 in forum WoW Memory Editing
    Replies: 10
    Last Post: 07-06-2008, 08:54 PM
All times are GMT -5. The time now is 06:58 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search