wow classic menu

User Tag List

Thread: wow classic

Results 1 to 14 of 14
  1. #1
    mikeymike's Avatar Active Member
    Reputation
    66
    Join Date
    Jan 2008
    Posts
    99
    Thanks G/R
    2/14
    Trade Feedback
    1 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    wow classic

    im looking for a bit of help, I cant seem to read any of classic memory. heres a simple test I don't for Player name but its not right. and advice is much help. thanks

    using System; using System.Collections.Generic; using System.Diagnostics; usi - Pastebin.com

    wow classic
  2. #2
    SatyPardus's Avatar Active Member
    Reputation
    15
    Join Date
    Nov 2014
    Posts
    24
    Thanks G/R
    15/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hello.

    The player name is null terminated and in UTF8 encoding.

    A little helper function that might be useful to you: (Don't know where it's from anymore)

    Code:
            private byte[] ReadNullTerminatedBytes(ulong address)
            {
                int returnLength = 0;
                byte[] ret = new byte[0];
                int size = 0;
                byte b = 0;
    
                while (true)
                {
                    ReadProcessMemory(ProcessHandle, address++, out b, Marshal.SizeOf(b), out returnLength);
                    if (b == 0)
                        return ret;
                    else
                    {
                        Array.Resize(ref ret, size + 1);
                        ret[size++] = b;
                    }
                }
            }
            public string ReadUTF8String(ulong address)
            {
                return Encoding.UTF8.GetString(ReadNullTerminatedBytes(address));
            }

  3. #3
    xalcon's Avatar Contributor ふたなり
    Authenticator enabled
    Reputation
    198
    Join Date
    Oct 2008
    Posts
    291
    Thanks G/R
    20/58
    Trade Feedback
    0 (0%)
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    @mikeymike: You need to use UTF-8, not Unicode.


    @SatyPardus:
    Originally Posted by SatyPardus View Post
    Hello.

    The player name is null terminated and in UTF8 encoding.

    A little helper function that might be useful to you: (Don't know where it's from anymore)

    Code:
            private byte[] ReadNullTerminatedBytes(ulong address)
            {
                int returnLength = 0;
                byte[] ret = new byte[0];
                int size = 0;
                byte b = 0;
    
                while (true)
                {
                    ReadProcessMemory(ProcessHandle, address++, out b, Marshal.SizeOf(b), out returnLength);
                    if (b == 0)
                        return ret;
                    else
                    {
                        Array.Resize(ref ret, size + 1);
                        ret[size++] = b;
                    }
                }
            }
            public string ReadUTF8String(ulong address)
            {
                return Encoding.UTF8.GetString(ReadNullTerminatedBytes(address));
            }
    While this code would work, its a horrible way of doing it.
    • The code starts with a size 0 byte array
    • it uses one read per byte
    • it grows the array each time it doesn't find a termination byte
    • it uses Mashal.sizeof() in a loop while the size is already known (its 1...)
    • There is no upper limit for the string size to prevent uncontrolled run-off


    Just read multiple bytes into a properly sized buffer. Reading 32 bytes at once for example will yield the player name in more than 99% of the scenarios (since there wont be many players that have a 4-byte UTF8 character for each character in their name - and even then, it would be a maximum of 49 bytes)

    The following solution is still not perfect (i dont really use ReadProcessMemory). It assumes that the memory region that is being accessed is valid, readable, etc. Its also missing partial read checks.
    Code:
    private static string ReadString(IntPtr process, IntPtr address, Encoding encoding = null, int sizeLimit = 256, int batchSize = 32)
    {
        var buffer = new byte[batchSize];
        var list = new List<byte>();
        int nullIndex;
        do
        {
            if (!ReadProcessMemory(process, address + list.Count, buffer, buffer.Length, out var numberOfBytesRead))
                throw new InvalidOperationException("Unable to read memory");
    
            nullIndex = Array.FindIndex(buffer, b => b == 0);
            list.AddRange(buffer.Take(nullIndex == -1 ? numberOfBytesRead : nullIndex));
            if (nullIndex >= 0)
                break;
        } while (list.Count < sizeLimit);
        return (encoding ?? Encoding.UTF8).GetString(list.ToArray());
    }
    Last edited by xalcon; 10-26-2019 at 03:26 PM.
    "Threads should always commit suicide - they should never be murdered" - DirectX SDK

  4. Thanks mazer (1 members gave Thanks to xalcon for this useful post)
  5. #4
    mikeymike's Avatar Active Member
    Reputation
    66
    Join Date
    Jan 2008
    Posts
    99
    Thanks G/R
    2/14
    Trade Feedback
    1 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ok what about reading GUID? I couldn't seem to get your method to work for name, but SatyPardus method did and his also might have worked for objMgr as well but not sure.

  6. #5
    mikeymike's Avatar Active Member
    Reputation
    66
    Join Date
    Jan 2008
    Posts
    99
    Thanks G/R
    2/14
    Trade Feedback
    1 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So here is my memory read class. does not work any help?

    Code:
    [DllImport("kernel32.dll")]
            public static extern bool ReadProcessMemory(IntPtr hProcess,
                ulong lpBaseAddress, out byte lpBuffer, int dwSize, out int lpNumberOfBytesRead);
            
            public static byte[] ReadBytes(IntPtr process, ulong address)
            {
                int returnLength = 0;
                byte[] ret = new byte[0];
                int size = 0;
                byte b = 0;
    
                while (true)
                {
                    ReadProcessMemory(process, address++, out b, Marshal.SizeOf(b), out returnLength);
                    if (b == 0)
                        return ret;
                    else
                    {
                        Array.Resize(ref ret, size + 1);
                        ret[size++] = b;
                    }
                }
            }
    
            public static ulong readUInt64(IntPtr process, IntPtr address)
            {
                byte[] ba = ReadBytes(process, (ulong)address.ToInt64());
                return BitConverter.ToUInt64(ba, 0);
            }
    
            public static uint readUInt32(IntPtr process, IntPtr address)
            {
                byte[] ba = ReadBytes(process, (ulong)address.ToInt64());
                return BitConverter.ToUInt32(ba, 0);
            }
    
            public static ushort readUInt16(IntPtr process, IntPtr address)
            {
                byte[] ba = ReadBytes(process, (ulong)address.ToInt64());
                return BitConverter.ToUInt16(ba, 0);
            }
    
            public static float readFloat(IntPtr process, IntPtr address)
            {
                byte[] ba = ReadBytes(process, (ulong)address.ToInt64());
                return BitConverter.ToSingle(ba, 0);
            }
    and im calling these

    Code:
    uint objManagerPointer = MemoryReader.readUInt32(WoW_Instance.getProcess().Handle, WoW_Instance.baseAddress + 0x232DED8);
    ulong GUID = MemoryReader.readUInt64(WoW_Instance.getProcess().Handle, WoW_Instance.baseAddress. + 0x26243D0);
    uint firstObj = MemoryReader.readUInt32(WoW_Instance.getProcess().Handle, new IntPtr(objManagerPointer + 0x18));
    any help is much appreciated thanks.

  7. #6
    ChrisIsMe's Avatar Contributor
    Reputation
    164
    Join Date
    Apr 2017
    Posts
    210
    Thanks G/R
    67/100
    Trade Feedback
    0 (0%)
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by mikeymike View Post
    ok what about reading GUID? I couldn't seem to get your method to work for name, but SatyPardus method did and his also might have worked for objMgr as well but not sure.
    struct GUID {
    int guid1;
    int guid2;
    int guid3;
    int guid4;
    };

  8. #7
    mikeymike's Avatar Active Member
    Reputation
    66
    Join Date
    Jan 2008
    Posts
    99
    Thanks G/R
    2/14
    Trade Feedback
    1 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    but my read function isn't reading right I don't think.

    Code:
    uint objManagerPointer = MemoryReader.readUInt32(WoW_Instance.getProcess().Handle, WoW_Instance.baseAddress + 0x232DED8);
    pretty sure that's reading wrong too.

  9. #8
    mazer's Avatar Member Authenticator enabled
    Reputation
    11
    Join Date
    Sep 2007
    Posts
    69
    Thanks G/R
    7/5
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by ChrisIsMe View Post
    struct GUID {
    int guid1;
    int guid2;
    int guid3;
    int guid4;
    };
    the Int128 implementation is also worth to mention:
    WowMoPObjMgrTest/Int128.cs at master . tomrus88/WowMoPObjMgrTest . GitHub
    usage can be found in the other source files

    edit: there is a nuget package for Int128 and UInt128 too:
    package name: UltimateOrb.Int128
    GitHub - LEI-Hongfaan/UltimateOrb.Int128: Provides Int128 and UInt128.
    Last edited by mazer; 10-27-2019 at 01:50 AM.

  10. #9
    NoxiaZ's Avatar Active Member
    Reputation
    23
    Join Date
    May 2019
    Posts
    101
    Thanks G/R
    21/12
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    With C# there are no need for any external library to obtain a int 128 bit class

    Just use: BigInteger Struct (System.Numerics) | Microsoft Docs

    Where you as well have access to Vector3, ViewMatrix4x4 and everything else needed for Vector math.

  11. #10
    NoxiaZ's Avatar Active Member
    Reputation
    23
    Join Date
    May 2019
    Posts
    101
    Thanks G/R
    21/12
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by mikeymike View Post
    but my read function isn't reading right I don't think.

    Code:
    uint objManagerPointer = MemoryReader.readUInt32(WoW_Instance.getProcess().Handle, WoW_Instance.baseAddress + 0x232DED8);
    pretty sure that's reading wrong too.
    Pointers are 64bit, så use UInt64 instead.

  12. #11
    xalcon's Avatar Contributor ふたなり
    Authenticator enabled
    Reputation
    198
    Join Date
    Oct 2008
    Posts
    291
    Thanks G/R
    20/58
    Trade Feedback
    0 (0%)
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Ofc its not working. You should stop using code that you don't understand because your "ReadBytes" method is just wrong. It works for Null-Terminated strings but not for anything else.
    "Threads should always commit suicide - they should never be murdered" - DirectX SDK

  13. #12
    mazer's Avatar Member Authenticator enabled
    Reputation
    11
    Join Date
    Sep 2007
    Posts
    69
    Thanks G/R
    7/5
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by NoxiaZ View Post
    With C# there are no need for any external library to obtain a int 128 bit class

    Just use: BigInteger Struct (System.Numerics) | Microsoft Docs

    Where you as well have access to Vector3, ViewMatrix4x4 and everything else needed for Vector math.
    good to know, didn't look further into this because i knew of the int128 stuff.
    allready using system.numerics so switching to it may saves me one dependency.

  14. #13
    mikeymike's Avatar Active Member
    Reputation
    66
    Join Date
    Jan 2008
    Posts
    99
    Thanks G/R
    2/14
    Trade Feedback
    1 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by xalcon View Post
    Ofc its not working. You should stop using code that you don't understand because your "ReadBytes" method is just wrong. It works for Null-Terminated strings but not for anything else.
    example please?

  15. #14
    xalcon's Avatar Contributor ふたなり
    Authenticator enabled
    Reputation
    198
    Join Date
    Oct 2008
    Posts
    291
    Thanks G/R
    20/58
    Trade Feedback
    0 (0%)
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by mikeymike View Post
    example please?
    It's not like there are a million samples on the internet on how to read memory....

    This code was part of an old project, I only updated some of the code to dotnet core 3.0
    You might need VS2019 to open it.

    xalcon/ClassicObjectManager - Gogs
    Last edited by xalcon; 10-27-2019 at 01:50 PM.
    "Threads should always commit suicide - they should never be murdered" - DirectX SDK

Similar Threads

  1. Molten Core WoW - Classic WoW Server
    By Thelovefool in forum WoW Emulator Server Listings
    Replies: 0
    Last Post: 04-19-2010, 07:31 AM
  2. [request] background for subtitle in style of wow classic logo
    By griwes in forum WoW ME Questions and Requests
    Replies: 3
    Last Post: 04-11-2010, 08:14 PM
  3. True WoW (Classic Server) 1x rates
    By Wriggly in forum WoW Emulator Server Listings
    Replies: 0
    Last Post: 08-09-2009, 01:21 PM
  4. WoW(classic) OST in BC
    By faisal_o in forum World of Warcraft General
    Replies: 5
    Last Post: 10-13-2007, 10:36 AM
All times are GMT -5. The time now is 09:22 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