Network: WoW Gold | WoW Accounts | MPS Games | FPSowned
MMOwned - World of Warcraft Exploits, Hacks, Bots and Guides
Homepage »      Register »      Hall of Fame »      Ranks And Awards »      Advertise »      Marketplace »
 
Sign up



Do you like this excellent information? Then Donate HERE to remove ads and support the MMOwned community.


Go Back   MMOwned - World of Warcraft Exploits, Hacks, Bots and Guides > World of Warcraft > Bots and Programs > WoW Memory Editing

WoW Memory Editing WoW Memory Editing for learning purposes only.
This section is more advanced than others on MMOwned Read the section specific rules, infractions will be given out if u break them!That is including the expectations! - If you don't meet them then don't post

Reply
 
LinkBack Thread Tools
  #1  
Old 10-01-2009
EmilyStrange is offline.
Corporal
  
 
Join Date: Jul 2009
Location: Los Angeles, CA
Posts: 27
Reputation: 18
Points: 214, Level: 1
Points: 214, Level: 1 Points: 214, Level: 1 Points: 214, Level: 1
Level up: 54%, 186 Points needed
Level up: 54% Level up: 54% Level up: 54%
Activity: 0.4%
Activity: 0.4% Activity: 0.4% Activity: 0.4%

[C#] A Memory Enumerator for Walking The Objects

This is a mini-tutorial that explains how to create an enumerator to walk the list of objects in the object manager.

Objects in the memory space of the World of Warcraft game client are held in a linked list that can be iterated over once you have the base address of the in-game Object Manager class. Walking that list of memory addresses can be a troublesome issue for many would-be developers. The easiest way that I have found, for C# development, is to create an enumerable list of memory addresses which can be treated just like any other collection to be iterated over.

Fortunately for C# developrs, creating a list of memory addresses is trivial using the enumerator interfaces built in to .NET.

The two classes provided below work by taking the pointer to the game client object manager class, and iterating over the linked list structure in-situ. Rather than doing the dirty work of juggling pointers in your own code, and trying to detect if you have run off the end of the linked list, you can simply use the built-in “foreach” loop structure of whatever your favourite .NET language is to retrieve the memory address of each game object. From there it is possible to write a wrapper class to manipulate the game object, or overlay the appropriate game object structure at the memory address.

A trivial example that makes use of the enumerable and enumerator classes is provided that walks the linked list of Warcraft game objects.

In the Enumerator class given below the “ObjectManagerPtr” is determined in the usual manner for accessing the list of locally cached in-game objects.

Code:
public class ObjectMemoryAddresses : IEnumerable
{
    public ObjectMemoryAddresses()
    {
    }

    public IEnumerator GetEnumerator()
    {
        return (new ObjectMemoryAddressesEnumerator());
    }

}

public class ObjectMemoryAddressesEnumerator : IEnumerator
{
    // The following two offsets apply to the 3.2.2a game client.
    public const uint OBJECT_LIST_OFFSET = 0x70;
    public const uint NEXT_OBJECT_OFFSET = 0x3C;
    private uint m_currentAddress = 0;

    public ObjectMemoryAddressesEnumerator()
    {
    }

    private uint GetNextAddress()
    {
        if (m_currentAddress == 0)
        {
            m_currentAddress = ObjectManagerPtr + OBJECT_LIST_OFFSET;
        }

        return MemoryEditor.ReadUInt(m_currentAddress + NEXT_OBJECT_OFFSET);
    }

    private bool IsValidAddress(uint address)
    {
        if (address == 0)
        {
            return (false);
        }

        if ((address & 1) != 0)
        {
            return (false);
        }

        if (address == m_currentAddress)
        {
            return (false);
        }

        return (true);
    }

    public bool MoveNext()
    {
        uint newAddress = GetNextAddress();
        if (!IsValidAddress(newAddress))
        {
            m_currentAddress = uint.MaxValue;
            return (false);
        }

        m_currentAddress = newAddress;
        return (true);
    }

    public void Reset()
    {
        m_currentAddress = 0;
    }

    public object Current
    {
        get
        {
            if ((m_currentAddress == 0) || (m_currentAddress == uint.MaxValue))
            {
                throw new InvalidOperationException();
            }

            return (m_currentAddress);
        }
    }

}
Example usage:

Code:
List<WowObject> objectList = new List<WowObject>();

ObjectMemoryAddresses objectMemory = new ObjectMemoryAddresses();
// get the memory address of each object
foreach (uint memoryAddress in objectMemory)
{
  objectList.Add(GetWoWObjectFromPtr(memoryAddress));
}
You can also apply this same enumerator technique to walking the player name cache or the auras. I believe that the auras and the player name cache are both stored in a C++ STL Map or something similar because of the “two lists” that are apparent in the memory structure. Most game client name cache functions found in the wild emulate the functionality of a C++ STL Map lookup.
Reply With Quote


Donate to remove ads, get your "DONATOR title, and get access to the MMOwned community's elite Shoutbawx.

  #2  
Old 10-01-2009
Neverhaven is offline.
Corporal
  
 
Join Date: Sep 2009
Location: localhost
Posts: 16
Reputation: 5
Points: 19, Level: 1
Points: 19, Level: 1 Points: 19, Level: 1 Points: 19, Level: 1
Level up: 5%, 381 Points needed
Level up: 5% Level up: 5% Level up: 5%
Activity: 1.3%
Activity: 1.3% Activity: 1.3% Activity: 1.3%
Looks very good, and it's informative. It's nice to see someone using C# and actually using the features. It's sad to see people making stuff in C# and just treating it like a basic script language.
Anyways
Reply With Quote
  #3  
Old 10-02-2009
namelessgnome's Avatar
namelessgnome is offline.
Contributor
  
 
Join Date: May 2007
Location: Sweden
Posts: 263
Reputation: 100
Points: 1,019, Level: 2
Points: 1,019, Level: 2 Points: 1,019, Level: 2 Points: 1,019, Level: 2
Level up: 24%, 381 Points needed
Level up: 24% Level up: 24% Level up: 24%
Activity: 10.1%
Activity: 10.1% Activity: 10.1% Activity: 10.1%
Great job! +REP

I agree with Neverhaven about people being unable to use the functionality of the .net framework. IEnumerable is very important to master because it is the foundation of the entire System.Collections namespace.
__________________

Get a signature like this one for free
http://www.mmowned.com/forums/graphics/249322-service-video-effects-userbars-signatures.htm
Reply With Quote
  #4  
Old 10-02-2009
Hyru is offline.
Sergeant
  
 
Join Date: Jun 2008
Posts: 41
Reputation: 36
Points: 580, Level: 1
Points: 580, Level: 1 Points: 580, Level: 1 Points: 580, Level: 1
Level up: 36%, 320 Points needed
Level up: 36% Level up: 36% Level up: 36%
Activity: 0.9%
Activity: 0.9% Activity: 0.9% Activity: 0.9%
Quote:
Originally Posted by Neverhaven View Post
Looks very good, and it's informative. It's nice to see someone using C# and actually using the features. It's sad to see people making stuff in C# and just treating it like a basic script language.
Anyways
Don't forget LINQ:

Quote:
var friends = Client.World.GetAllPlayers().Where(x => x.Value.IsAlive && Notoriety.IsFriend(Client.World.Character, x.Value));
var health = friends.OrderBy(x => x.Value.HPCur);
Reply With Quote
  #5  
Old 10-02-2009
Neverhaven is offline.
Corporal
  
 
Join Date: Sep 2009
Location: localhost
Posts: 16
Reputation: 5
Points: 19, Level: 1
Points: 19, Level: 1 Points: 19, Level: 1 Points: 19, Level: 1
Level up: 5%, 381 Points needed
Level up: 5% Level up: 5% Level up: 5%
Activity: 1.3%
Activity: 1.3% Activity: 1.3% Activity: 1.3%
That reminds me, I still need to learn some more about lambda operators.
Reply With Quote
  #6  
Old 10-04-2009
Shutzler is offline.
New User
  
 
Join Date: Sep 2009
Posts: 51
Reputation: 3
Points: 211, Level: 1
Points: 211, Level: 1 Points: 211, Level: 1 Points: 211, Level: 1
Level up: 53%, 189 Points needed
Level up: 53% Level up: 53% Level up: 53%
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
nice done!

However, some things are still missing(when you miss it all).

I have my own memory read functions but where do you put in where to start reading objects?

AND

Could you paste WowObject structure? (the whole thingy, what do you grab and so).
Reply With Quote
  #7  
Old 10-04-2009
Robske's Avatar
Robske is offline.
Contributor
  
 
Join Date: May 2007
Location: Dragon Shores
Posts: 690
Reputation: 167
Points: 3,849, Level: 6
Points: 3,849, Level: 6 Points: 3,849, Level: 6 Points: 3,849, Level: 6
Level up: 28%, 651 Points needed
Level up: 28% Level up: 28% Level up: 28%
Activity: 10.8%
Activity: 10.8% Activity: 10.8% Activity: 10.8%

Quote:
Originally Posted by Shutzler View Post
nice done!

However, some things are still missing(when you miss it all).

I have my own memory read functions but where do you put in where to start reading objects?

Code:
        if (m_currentAddress == 0)
        {
            m_currentAddress = ObjectManagerPtr + OBJECT_LIST_OFFSET;
        }
        return MemoryEditor.ReadUInt(m_currentAddress + NEXT_OBJECT_OFFSET);
But it seems she accesses the first object in a different manner than I'm used to. If ObjectManagerPtr + 0x70 points to the first object, doesn't this implementation skip the first object?


Quote:
Originally Posted by Shutzler View Post
Could you paste WowObject structure? (the whole thingy, what do you grab and so).

Why not ask for the entire folder instead?
__________________
“Saying that Java is nice because it works on all OSes is like saying that anal sex is nice because it works on all genders.”
“If Java had true garbage collection, most programs would delete themselves upon execution.”
Reply With Quote
  #8  
Old 10-04-2009
Shutzler is offline.
New User
  
 
Join Date: Sep 2009
Posts: 51
Reputation: 3
Points: 211, Level: 1
Points: 211, Level: 1 Points: 211, Level: 1 Points: 211, Level: 1
Level up: 53%, 189 Points needed
Level up: 53% Level up: 53% Level up: 53%
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
Quote:
Originally Posted by Robske View Post

Why not ask for the entire folder instead?
I dont understand, entire folder? I just want a list of offset to stuff. like within playeobject or targetobj(for its HP), where to find xp, mana, rage, position ++
Reply With Quote
  #9  
Old 10-06-2009
Ellesar1 is offline.
Site Donator
  
 
Join Date: Feb 2009
Posts: 60
Reputation: 12
Points: 577, Level: 1
Points: 577, Level: 1 Points: 577, Level: 1 Points: 577, Level: 1
Level up: 36%, 323 Points needed
Level up: 36% Level up: 36% Level up: 36%
Activity: 2.5%
Activity: 2.5% Activity: 2.5% Activity: 2.5%

he wants to say that you should be satisfied with what was written by the thread author. If you have the WowObject structure you could soon ask for a complete bot and therefore "for the entire folder" (where the source is stored)

For me as a beginner to all this memory editing stuff I am happy that one shows an easy example on how to get the objects from the wow memory. The objects are the base for nearly every useful bot.

for the tutorial.

i still have the question:

how is the "ObjectManagerPtr" exactly defined which you are using in the following line
Code:
m_currentAddress = ObjectManagerPtr + OBJECT_LIST_OFFSET;
Reply With Quote
  #10  
Old 10-06-2009
Robske's Avatar
Robske is offline.
Contributor
  
 
Join Date: May 2007
Location: Dragon Shores
Posts: 690
Reputation: 167
Points: 3,849, Level: 6
Points: 3,849, Level: 6 Points: 3,849, Level: 6 Points: 3,849, Level: 6
Level up: 28%, 651 Points needed
Level up: 28% Level up: 28% Level up: 28%
Activity: 10.8%
Activity: 10.8% Activity: 10.8% Activity: 10.8%

Quote:
Originally Posted by Ellesar1 View Post
For me as a beginner to all this memory editing stuff I am happy that one shows an easy example on how to get the objects from the wow memory. The objects are the base for nearly every useful bot.

for the tutorial.

i still have the question:

how is the "ObjectManagerPtr" exactly defined which you are using in the following line
Code:
m_currentAddress = ObjectManagerPtr + OBJECT_LIST_OFFSET;
I have no clue as to where it came from. But it should work if m_currentAddress is assigned the address of the first object in the linked list.
Which is: [[[g_ClientConnection]+curMgrOffset]+firstObjectOffset]
(That would however still skip the first object)
__________________
“Saying that Java is nice because it works on all OSes is like saying that anal sex is nice because it works on all genders.”
“If Java had true garbage collection, most programs would delete themselves upon execution.”
Reply With Quote
  #11  
Old 10-06-2009
EmilyStrange is offline.
Corporal
  
 
Join Date: Jul 2009
Location: Los Angeles, CA
Posts: 27
Reputation: 18
Points: 214, Level: 1
Points: 214, Level: 1 Points: 214, Level: 1 Points: 214, Level: 1
Level up: 54%, 186 Points needed
Level up: 54% Level up: 54% Level up: 54%
Activity: 0.4%
Activity: 0.4% Activity: 0.4% Activity: 0.4%

Equivocal or equivalent?

If there is an error, or I have misinterpreted how the object list is laid out in memory, I will gladly provide a fix...

However, run this code against whatever solution you are currently using to retrieve your objects and see if they return identical results.

At the offset 0xAC in the Object Manager class is a pointer to the first object.
At the offset 0x3C within each object is a pointer to the next object.

Ergo:

Object Manager Ptr + 0x70 + 0x3C, i.e. Object Manager Ptr + 0xAC is a pointer to the first object

Current Object Ptr + 0x3C is a pointer to the next object

Odd that... don't you think?

This is the code I derived my solution from, and I modified this code from other sources found on the 'net by cleaning it up and renaming variables to make it more understandable.
Code:
        public const uint FIRST_OBJECT_OFFSET = 0xAC;
        public const uint NEXT_OBJECT_OFFSET = 0x3C;

        public List<WowObject> GetObjects()
        {
            List<WowObject> objectList = new List<WowObject>();
            uint currentObjectPtr = GetFirstObjectPtr();
            uint previousObjectPtr = 0;

            while ((currentObjectPtr != 0) && ((currentObjectPtr & 1) == 0) && (currentObjectPtr != previousObjectPtr))
            {
                System.Diagnostics.Debug.WriteLine("Object Addr = 0x" + currentObjectPtr.ToString("X"));
                objectList.Add(GetWoWObjectFromPtr(currentObjectPtr));
                previousObjectPtr = currentObjectPtr;
                currentObjectPtr = GetNextObjectPtr(currentObjectPtr);
            }

            return objectList;
        }

        private uint GetFirstObjectPtr()
        {
            return m_gameClient.MemoryEditor.ReadUInt(m_gameClient.ObjectManagerPtr + GameClient.FIRST_OBJECT_OFFSET);
        }

        private uint GetNextObjectPtr(uint CurrentObject)
        {
            return m_gameClient.MemoryEditor.ReadUInt(CurrentObject + GameClient.NEXT_OBJECT_OFFSET);
        }
Reply With Quote
  #12  
Old 10-06-2009
EmilyStrange is offline.
Corporal
  
 
Join Date: Jul 2009
Location: Los Angeles, CA
Posts: 27
Reputation: 18
Points: 214, Level: 1
Points: 214, Level: 1 Points: 214, Level: 1 Points: 214, Level: 1
Level up: 54%, 186 Points needed
Level up: 54% Level up: 54% Level up: 54%
Activity: 0.4%
Activity: 0.4% Activity: 0.4% Activity: 0.4%

If I run both versions whilst stood in Stormwind City, I get 410 objects returned, both with an identical list of addresses. And the Warcraft Radar shows 410 objects around me too. Let me know if I messed up my pointer arithmetic.
Reply With Quote
  #13  
Old 10-06-2009
Robske's Avatar
Robske is offline.
Contributor
  
 
Join Date: May 2007
Location: Dragon Shores
Posts: 690
Reputation: 167
Points: 3,849, Level: 6
Points: 3,849, Level: 6 Points: 3,849, Level: 6 Points: 3,849, Level: 6
Level up: 28%, 651 Points needed
Level up: 28% Level up: 28% Level up: 28%
Activity: 10.8%
Activity: 10.8% Activity: 10.8% Activity: 10.8%

Quote:
Originally Posted by EmilyStrange View Post

Object Manager Ptr + 0x70 + 0x3C, i.e. Object Manager Ptr + 0xAC is a pointer to the first object
Dang, ofcourse. My assumption was false, no object is skipped.
__________________
“Saying that Java is nice because it works on all OSes is like saying that anal sex is nice because it works on all genders.”
“If Java had true garbage collection, most programs would delete themselves upon execution.”
Reply With Quote
  #14  
Old 10-06-2009
Tanaris4 is offline.
Sergeant Major
  
 
Join Date: Oct 2008
Posts: 146
Reputation: 12
Points: 1,169, Level: 2
Points: 1,169, Level: 2 Points: 1,169, Level: 2 Points: 1,169, Level: 2
Level up: 54%, 231 Points needed
Level up: 54% Level up: 54% Level up: 54%
Activity: 6.2%
Activity: 6.2% Activity: 6.2% Activity: 6.2%

@Emily thanks, new post created

Last edited by Tanaris4; 10-07-2009 at 10:11 AM.
Reply With Quote
  #15  
Old 10-06-2009
EmilyStrange is offline.
Corporal
  
 
Join Date: Jul 2009
Location: Los Angeles, CA
Posts: 27
Reputation: 18
Points: 214, Level: 1
Points: 214, Level: 1 Points: 214, Level: 1 Points: 214, Level: 1
Level up: 54%, 186 Points needed
Level up: 54% Level up: 54% Level up: 54%
Activity: 0.4%
Activity: 0.4% Activity: 0.4% Activity: 0.4%

Not here...

I don't believe your question is very applicable to this thread, and neither is the Objective-C code snippet when this thread is clearly about using a C# enumerator?

If you want to move your post to a separate thread, I would be willing to help you there on locating and reading the Object Manager and pointers, but all you have done now is confuse the issue for other people reading this.
Reply With Quote
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are On



All times are GMT -4. The time now is 03:18 PM.




Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.1

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493