Need help understanding IDA C-Pseudocode menu

User Tag List

Results 1 to 10 of 10
  1. #1
    siriuz's Avatar Active Member
    Reputation
    78
    Join Date
    Jun 2009
    Posts
    69
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Need help understanding IDA C-Pseudocode

    I want to read some stuff from memory like avarage wait time for raid finder queue. So I searched for a wow api function from which I can get this stuff.
    In this case its GetLFGQueueStats() ... so I went into IDA and its generates me this C-Pseudocode from that function, that I maybe don't understand correctly.

    I found my desired value at line 70:
    Code:
    //return 16: myWait
    lua_pushnumber(a2, (double)v6[1]);
    So my value is in array v6 at index 1, right?

    v6 itself is filled at line 32:
    Code:
    v6 = &dword_116EA40[9 * v4], dword_116EA40[9 * v4]
    Dunno what this exactly does but v4=2 when looking for Raid Finder queue, because a=3 then:
    Code:
    // a2 = 3 --> Raid Finder
    v3 = lua_tointeger(a2);
    v4 = v3 - 1;
    so its:
    Code:
    v6 = &dword_116EA40[18], dword_116EA40[18]
    Does this mean at offset 116EA40 (not rebased) is an array and at index 18 of it is another array (v6)?
    So does this finally mean, that there is a 2D Array at 116EA40, or do I completly misunderstand this things?

    Unfortunately I have no idea how I can read an array from memory, so I tried something like:

    Code:
    Array[,] arr = Memory.Read<Array[,]>(Memory.BaseAddress + 0xD6EA40);
    double value = Convert.ToDouble(arr[18, 1]);
    But yeah ... that doesnt work since arr is null everytime

    Can someone pls put in the right way?

    Need help understanding IDA C-Pseudocode
  2. #2
    pladi's Avatar Member
    Reputation
    4
    Join Date
    Jan 2009
    Posts
    11
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Just a little note: never trust the output you get from using hex-rays, as not everything is translated correctly :P

    As for your questions:
    1) It's actually a struct pointed to by v6, where myWait is stored as the second field (e.g. at offset 0x4 from the structs beginning).
    2) That means that a pointer is stored at 116EA40 + 36 * v4 (not rebased - this is where hex-rays translated incorrectly) for the struct containing myWait.

    At a quick glance in IDA, it seems as if the struct (not completed) looks somewhat like this:

    struct QueueStats
    {
    uint Id;
    uint myWait;
    uint averageWait;
    uint tankWait;
    uint healWait;
    uint damageWait;
    }
    Last edited by pladi; 02-10-2013 at 04:23 PM.

  3. #3
    TOM_RUS's Avatar Legendary
    Reputation
    914
    Join Date
    May 2008
    Posts
    699
    Thanks G/R
    0/52
    Trade Feedback
    0 (0%)
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Code:
    struct LFGQueueStats
    {
      DWORD LfgDungeonsId;
      DWORD myWait;
      DWORD averageWait;
      DWORD tankWait;
      DWORD healerWait;
      DWORD damageWait;
      BYTE tankNeeds;
      BYTE healerNeeds;
      BYTE dpsNeeds;
      BYTE pad0;
      DWORD time;
      DWORD queuedTime;
    };
    
    LFGQueueStats g_LfgQueueStats[4]; // @ .data:0116EA40 not rebased
    
    signed int __cdecl Script_GetLFGQueueStats(int pLuaState)
    {
      signed int numRetArgs; // eax@2
      int category; // eax@3
      int zbCategory; // esi@3
      int v4; // eax@4
      LFGQueueStats *pLfgStats; // ebx@7
      LfgDungeonsRec *pLfgDunRec; // eax@8
      int instanceSubType; // ST3C_4@9
      int queuedTime; // st7@9
    
      // hasData,  leaderNeeds, tankNeeds, healerNeeds, dpsNeeds, totalTanks, totalHealers, totalDPS, instanceType,
      // instanceSubType, instanceName, averageWait, tankWait, healerWait, damageWait, myWait, queuedTime = GetLFGQueueStats(category);
      if ( lua_isnumber(pLuaState, 1) )
      {
        category = lua_tointeger(pLuaState, 1);
        zbCategory = category - 1;
        if ( (category - 1) > 3 )
        {
          luaL_error(pLuaState, "Invalid category");
          numRetArgs = 0;
        }
        else
        {
          v4 = sub_AA0AB0(category - 1);
          pLfgStats = &g_LfgQueueStats[zbCategory];
          if ( v4 && *(v4 + 40) && *(v4 + 42) && pLfgStats && pLfgStats->LfgDungeonsId )
          {
            lua_pushboolean(pLuaState, 1);          // hasData
            lua_pushnumber(pLuaState, 0.0);         // leaderNeeds
            lua_pushnumber(pLuaState, pLfgStats->tankNeeds);// tankNeeds
            lua_pushnumber(pLuaState, pLfgStats->healerNeeds);// healerNeeds
            lua_pushnumber(pLuaState, pLfgStats->dpsNeeds);// dpsNeeds
            pLfgDunRec = LfgDungeonsDB::GetRow(&g_LfgDungeonsDB, pLfgStats->LfgDungeonsId);
            if ( pLfgDunRec )
            {
              lua_pushnumber(pLuaState, pLfgDunRec->totalTanks);// totalTanks
              lua_pushnumber(pLuaState, pLfgDunRec->totalHealers);// totalHealers
              lua_pushnumber(pLuaState, pLfgDunRec->totalDPS);// totalDPS
              lua_pushnumber(pLuaState, pLfgDunRec->instanceType);// instanceType
              instanceSubType = LfgDungeonsDB::GetInstanceSubType(pLfgDunRec);
              lua_pushnumber(pLuaState, instanceSubType);// instanceSubType
              lua_pushstring(pLuaState, pLfgDunRec->instanceName);// instanceName
              lua_pushnumber(pLuaState, pLfgStats->averageWait);// averageWait
              lua_pushnumber(pLuaState, pLfgStats->tankWait);// tankWait
              lua_pushnumber(pLuaState, pLfgStats->healerWait);// healerWait
              lua_pushnumber(pLuaState, pLfgStats->damageWait);// damageWait
              lua_pushnumber(pLuaState, pLfgStats->myWait);// myWait
              queuedTime = pLfgStats->queuedTime;
              if ( (pLfgStats->queuedTime & 0x80000000u) != 0 )
                queuedTime = queuedTime + *&dword_D282A8;
              lua_pushnumber(pLuaState, queuedTime * 0.001);// queuedTime
              numRetArgs = 17;
            }
            else
            {
              lua_pushnil(pLuaState);
              lua_pushnil(pLuaState);
              lua_pushnil(pLuaState);
              lua_pushnil(pLuaState);
              lua_pushnil(pLuaState);
              lua_pushnil(pLuaState);
              lua_pushnil(pLuaState);
              lua_pushnil(pLuaState);
              lua_pushnil(pLuaState);
              lua_pushnil(pLuaState);
              lua_pushnil(pLuaState);
              lua_pushnil(pLuaState);
              numRetArgs = 17;
            }
          }
          else
          {
            numRetArgs = 0;
          }
        }
      }
      else
      {
        luaL_error(pLuaState, "Usage: GetLFGQueueStats(LE_LFG_CATEGORY)");
        numRetArgs = 0;
      }
      return numRetArgs;
    }
    Last edited by TOM_RUS; 02-10-2013 at 04:49 PM.

  4. #4
    siriuz's Avatar Active Member
    Reputation
    78
    Join Date
    Jun 2009
    Posts
    69
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Just a little note: never trust the output you get from using hex-rays, as not everything is translated correctly :P
    Whats your tip to get better / correct results? I'm very new to this whole topic, but very interested in learning it ...

    Originally Posted by pladi View Post
    2) That means that a pointer is stored at 116EA40 + 36 * v4 (not rebased - this is where hex-rays translated incorrectly) for the struct containing myWait.
    116EA40 + 36 * 2 = 116EA88
    116EA88 - 0x400000 = D6EA88
    But there is also nothing :-/

    Originally Posted by TOM_RUS
    Code:
    LFGQueueStats g_LfgQueueStats[4]; // @ .data: not rebased
    How do I have to understand this notation? Pointer to struct at 0116EA40 + 4 ?

  5. #5
    TOM_RUS's Avatar Legendary
    Reputation
    914
    Join Date
    May 2008
    Posts
    699
    Thanks G/R
    0/52
    Trade Feedback
    0 (0%)
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by siriuz View Post
    How do I have to understand this notation? Pointer to struct at 0116EA40 + 4 ?
    There's an array of structs LFGQueueStats with size 4 at 0116EA40, one for each LFG category:

    Code:
    enum LE_LFG_CATEGORY
    {
        LE_LFG_CATEGORY_LFD = 1
        LE_LFG_CATEGORY_LFR = 2
        LE_LFG_CATEGORY_RF = 3
        LE_LFG_CATEGORY_SCENARIO = 4
    }
    those values are passed to lua, then they subtract 1 to make them zero based and use it as an index in that g_LfgQueueStats array.
    Last edited by TOM_RUS; 02-10-2013 at 06:55 PM.

  6. #6
    siriuz's Avatar Active Member
    Reputation
    78
    Join Date
    Jun 2009
    Posts
    69
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by TOM_RUS View Post
    There's an array of structs LFGQueueStats with size 4 at 0116EA40 for each LFG category
    Yeah, that makes even more sense, thx man!

    Now it should be more clear at all for me and I can go on with figuring out how to read this kind of shit

  7. #7
    siriuz's Avatar Active Member
    Reputation
    78
    Join Date
    Jun 2009
    Posts
    69
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    For completeness I just throw in my C# Code here. Maybe someone other comes across here with something similar and maybe find this useful:

    Code:
    class LFGQueueStats
    {
    
        public struct DataStruct
        {
            public int LfgDungeonsId;
            public int myWait;
            public int averageWait;
            public int tankWait;
            public int healerWait;
            public int damageWait;
            public byte tankNeeds;
            public byte healerNeeds;
            public byte dpsNeeds;
            public byte pad0;
            public uint time;
            public int queuedTime;
        }
    
        public static DataStruct getQueueStats(uint LE_LFG_CATEGORY)
        {
            DataStruct lfgQueue = new DataStruct();
            uint structSize = (uint)Marshal.SizeOf(lfgQueue);
            lfgQueue = Memory.ReadStruct<DataStruct>( Memory.BaseAddress + Offset.LFGQueueStats + ( structSize * (LE_LFG_CATEGORY - 1) ) );
    
            return lfgQueue;
        }
    
    }

  8. #8
    Corthezz's Avatar Elite User Authenticator enabled
    Reputation
    386
    Join Date
    Nov 2011
    Posts
    325
    Thanks G/R
    191/98
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks, helped me.
    +Rep

  9. #9
    siriuz's Avatar Active Member
    Reputation
    78
    Join Date
    Jun 2009
    Posts
    69
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hey Tom,

    I'm actually stuck at that dbc stuff of the Script_GetLFGQueueStats function.

    Code:
    pLfgDunRec = LfgDungeonsDB::GetRow(&g_LfgDungeonsDB, pLfgStats->LfgDungeonsId);
    Did I understand it correctly, that g_LfgDungeonsDB is the pointer (at 0xFFCA6C) to the LfgDungeons dbc?
    I found your dbc class ([WoW][5.0.4.16016] x86 Info Dump Thread) which should enable me to read that stuff, but how/where can I get information about the structure of a LfgDungeons record?

    I found http://www.pxr.dk/wowdev/wiki/index....FGDungeons.dbc but got confused because there is no totalTanks, totalHeal, totalDps ... or any equivalent.
    Last edited by siriuz; 02-26-2013 at 11:52 AM.

  10. #10
    JuJuBoSc's Avatar Banned for scamming CoreCoins Purchaser
    Reputation
    1019
    Join Date
    May 2007
    Posts
    922
    Thanks G/R
    1/3
    Trade Feedback
    1 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You can use DBC Viewer to figure out the structure yourself, I personally use one made by TOM_RUS which is the best I tried.

Similar Threads

  1. Replies: 1
    Last Post: 06-23-2013, 09:19 AM
  2. [Bot] I need help understanding which hexadecimal address to use :(
    By mrdennis87 in forum WoW Memory Editing
    Replies: 4
    Last Post: 02-22-2012, 01:03 PM
  3. Need help understanding how to transfer MPQ files/folders
    By Avalos in forum WoW ME Questions and Requests
    Replies: 0
    Last Post: 01-08-2011, 07:56 PM
  4. need help with shammy talents
    By jason in forum World of Warcraft General
    Replies: 5
    Last Post: 07-19-2006, 02:02 AM
  5. Need Help
    By Slumlorde in forum World of Warcraft General
    Replies: 4
    Last Post: 06-23-2006, 08:20 AM
All times are GMT -5. The time now is 06:33 PM. 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