Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Help needed - C# - Memory GetAddress always returnin 0

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking
View previous topic :: View next topic  
Author Message
d4ne
How do I cheat?
Reputation: 0

Joined: 06 Dec 2016
Posts: 7

PostPosted: Thu Dec 08, 2016 7:35 pm    Post subject: Help needed - C# - Memory GetAddress always returnin 0 Reply with quote

I'm trying to read some memory values, sadly the response would always be 0. It returned the real value once, but never again and I really don't get what's causing the wrong results.

I've found the memory.cs class in a YouTube tutorial: youtube (dot) com/watch?v=TWUK-fK7xD8 and the original class can be found here: matejtomcik (dot) com/Download/?n=CheatEngineCSharpHelpers

The memory.cs looks like the following:

Code:

using System;
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace InfiniteTrainer.CheatEngine
{
    /// <summary>
    /// Represents an access to a remote process memory
    /// </summary>
    public class Memory : IDisposable
    {
        private Process process;
        private IntPtr processHandle;
        private bool isDisposed;

        public const string OffsetPattern = "(\\+|\\-){0,1}(0x){0,1}[a-fA-F0-9]{1,}";

        /// <summary>
        /// Initializes a new instance of the Memory
        /// </summary>
        /// <param name="process">Remote process</param>
        public Memory(Process process)
        {
            if (process == null)
                throw new ArgumentNullException("process");

            this.process = process;
            processHandle = Win32.OpenProcess(
                Win32.ProcessAccessType.PROCESS_VM_READ | Win32.ProcessAccessType.PROCESS_VM_WRITE |
                Win32.ProcessAccessType.PROCESS_VM_OPERATION, true, (uint)process.Id);
            if (processHandle == IntPtr.Zero)
                throw new InvalidOperationException("Could not open the process");
        }

        #region IDisposable

        ~Memory()
        {
            Dispose(false);
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            if (isDisposed)
                return;
            Win32.CloseHandle(processHandle);
            process = null;
            processHandle = IntPtr.Zero;
            isDisposed = true;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets the process to which this memory is attached to
        /// </summary>
        public Process Process
        {
            get
            {
                return process;
            }
        }

        #endregion

        /// <summary>
        /// Finds module with the given name
        /// </summary>
        /// <param name="name">Module name</param>
        /// <returns></returns>
        protected ProcessModule FindModule(string name)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");
            foreach (ProcessModule module in process.Modules)
            {
                if (module.ModuleName.ToLower() == name.ToLower())
                    return module;
            }
            return null;
        }

        /// <summary>
        /// Gets module based address
        /// </summary>
        /// <param name="moduleName">Module name</param>
        /// <param name="baseAddress">Base address</param>
        /// <param name="offsets">Collection of offsets</param>
        /// <returns></returns>
        public IntPtr GetAddress(string moduleName, IntPtr baseAddress, int[] offsets)
        {
            if (string.IsNullOrEmpty(moduleName))
                throw new ArgumentNullException("moduleName");

            ProcessModule module = FindModule(moduleName);
            if (module == null)
                return IntPtr.Zero;
            else
            {
                //int address = module.BaseAddress.ToInt32() + baseAddress.ToInt32();
                long address = module.BaseAddress.ToInt64() + baseAddress.ToInt64();
                return GetAddress((IntPtr)address, offsets);
            }
        }

        /// <summary>
        /// Gets address
        /// </summary>
        /// <param name="baseAddress">Base address</param>
        /// <param name="offsets">Collection of offsets</param>
        /// <returns></returns>
        public IntPtr GetAddress(IntPtr baseAddress, int[] offsets)
        {
            if (baseAddress == IntPtr.Zero)
                throw new ArgumentException("Invalid base address");

            //int address = baseAddress.ToInt32();
            long address = baseAddress.ToInt64();

            if (offsets != null && offsets.Length > 0)
            {
                byte[] buffer = new byte[4];
                foreach (int offset in offsets)
                    address = ReadInt32((IntPtr)address) + offset;
            }

            return (IntPtr)address;
        }

        /// <summary>
        /// Gets address pointer
        /// </summary>
        /// <param name="address">Address</param>
        /// <returns></returns>
        public IntPtr GetAddress(string address)
        {
            if (string.IsNullOrEmpty(address))
                throw new ArgumentNullException("address");

            string moduleName = null;
            int index = address.IndexOf('"');
            if (index != -1)
            {
                // Module name at the beginning
                int endIndex = address.IndexOf('"', index + 1);
                if (endIndex == -1)
                    throw new ArgumentException("Invalid module name. Could not find matching \"");
                moduleName = address.Substring(index + 1, endIndex - 1);
                address = address.Substring(endIndex + 1);
            }

            int[] offsets = GetAddressOffsets(address);
            int[] _offsets = null;
            IntPtr baseAddress = offsets != null && offsets.Length > 0 ?
                (IntPtr)offsets[0] : IntPtr.Zero;
            if (offsets != null && offsets.Length > 1)
            {
                _offsets = new int[offsets.Length - 1];
                for (int i = 0; i < offsets.Length - 1; i++)
                    _offsets[i] = offsets[i + 1];
            }

            if (moduleName != null)
                return GetAddress(moduleName, baseAddress, _offsets);
            else
                return GetAddress(baseAddress, _offsets);
        }

        /// <summary>
        /// Gets address offsets
        /// </summary>
        /// <param name="address">Address</param>
        /// <returns></returns>
        protected static int[] GetAddressOffsets(string address)
        {
            if (string.IsNullOrEmpty(address))
                return new int[0];
            else
            {
                MatchCollection matches = Regex.Matches(address, OffsetPattern);
                int[] offsets = new int[matches.Count];
                string value;
                char ch;
                for (int i = 0; i < matches.Count; i++)
                {
                    ch = matches[i].Value[0];
                    if (ch == '+' || ch == '-')
                        value = matches[i].Value.Substring(1);
                    else
                        value = matches[i].Value;
                    offsets[i] = Convert.ToInt32(value, 16);
                    if (ch == '-')
                        offsets[i] = -offsets[i];
                }
                return offsets;
            }
        }

        /// <summary>
        /// Reads memory at the address
        /// </summary>
        /// <param name="address">Memory address</param>
        /// <param name="buffer">Buffer</param>
        /// <param name="size">Size in bytes</param>
        public void ReadMemory(IntPtr address, byte[] buffer, int size)
        {
            if (isDisposed)
                throw new ObjectDisposedException("Memory");
            if (buffer == null)
                throw new ArgumentNullException("buffer");
            if (size <= 0)
                throw new ArgumentException("Size must be greater than zero");
            if (address == IntPtr.Zero)
                throw new ArgumentException("Invalid address");

            uint read = 0;
            if (!Win32.ReadProcessMemory(processHandle, address, buffer, (uint)size, ref read) ||
                read != size)
                throw new AccessViolationException();
        }

        /// <summary>
        /// Writes memory at the address
        /// </summary>
        /// <param name="address">Memory address</param>
        /// <param name="buffer">Buffer</param>
        /// <param name="size">Size in bytes</param>
        public void WriteMemory(IntPtr address, byte[] buffer, int size)
        {
            if (isDisposed)
                throw new ObjectDisposedException("Memory");
            if (buffer == null)
                throw new ArgumentNullException("buffer");
            if (size <= 0)
                throw new ArgumentException("Size must be greater than zero");
            if (address == IntPtr.Zero)
                throw new ArgumentException("Invalid address");

            uint write = 0;
            if (!Win32.WriteProcessMemory(processHandle, address, buffer, (uint)size, ref write) ||
                write != size)
                throw new AccessViolationException();
        }

        /// <summary>
        /// Reads 32 bit signed integer at the address
        /// </summary>
        /// <param name="address">Memory address</param>
        /// <returns></returns>
        public int ReadInt32(IntPtr address)
        {
            byte[] buffer = new byte[4];
            ReadMemory(address, buffer, 4);
            return BitConverter.ToInt32(buffer, 0);
        }

        /// <summary>
        /// Reads 32 bit unsigned integer at the address
        /// </summary>
        /// <param name="address">Memory address</param>
        /// <returns></returns>
        public uint ReadUInt32(IntPtr address)
        {
            byte[] buffer = new byte[4];
            ReadMemory(address, buffer, 4);
            return BitConverter.ToUInt32(buffer, 0);
        }

        /// <summary>
        /// Reads single precision value at the address
        /// </summary>
        /// <param name="address">Memory address</param>
        /// <returns></returns>
        public float ReadFloat(IntPtr address)
        {
            byte[] buffer = new byte[4];
            ReadMemory(address, buffer, 4);
            return BitConverter.ToSingle(buffer, 0);
        }

        /// <summary>
        /// Reads double precision value at the address
        /// </summary>
        /// <param name="address">Memory address</param>
        /// <returns></returns>
        public double ReadDouble(IntPtr address)
        {
            byte[] buffer = new byte[8];
            ReadMemory(address, buffer, 8);
            return BitConverter.ToDouble(buffer, 0);
        }

        /// <summary>
        /// Writes 32 bit unsigned integer at the address
        /// </summary>
        /// <param name="address">Memory address</param>
        /// <param name="value">Value</param>
        /// <returns></returns>
        public void WriteUInt32(IntPtr address, uint value)
        {
            byte[] buffer = BitConverter.GetBytes(value);
            WriteMemory(address, buffer, 4);
        }

        /// <summary>
        /// Writes 32 bit signed integer at the address
        /// </summary>
        /// <param name="address">Memory address</param>
        /// <param name="value">Value</param>
        /// <returns></returns>
        public void WriteInt32(IntPtr address, int value)
        {
            byte[] buffer = BitConverter.GetBytes(value);
            WriteMemory(address, buffer, 4);
        }

        /// <summary>
        /// Writes single precision value at the address
        /// </summary>
        /// <param name="address">Memory address</param>
        /// <param name="value">Value</param>
        /// <returns></returns>
        public void WriteFloat(IntPtr address, float value)
        {
            byte[] buffer = BitConverter.GetBytes(value);
            WriteMemory(address, buffer, 4);
        }

        /// <summary>
        /// Writes double precision value at the address
        /// </summary>
        /// <param name="address">Memory address</param>
        /// <param name="value">Value</param>
        /// <returns></returns>
        public void WriteDouble(IntPtr address, double value)
        {
            byte[] buffer = BitConverter.GetBytes(value);
            WriteMemory(address, buffer, 8);
        }
    }
}


Had to change some code-lines in there because it's a 64 bit game and no 32 bit game.

The following changes where done:

Code:
int address = module.BaseAddress.ToInt32() + baseAddress.ToInt32();
// Got edited to the following line
long address = module.BaseAddress.ToInt64() + baseAddress.ToInt64();


and:

Code:

int address = baseAddress.ToInt32();
// Got edited to the following line
long address = baseAddress.ToInt64();


And I'm calling the function in the following way:

Code:

public void updatePlayerStatistic(int prestigeLevel)
{
    Process[] processes = Process.GetProcessesByName("iw7_ship");
    if (processes.Length > 0)
    {
        using (CheatEngine.Memory memory = new CheatEngine.Memory(processes[0]))
        {
            // Prestige code
            IntPtr prestigeAddress = memory.GetAddress("iw7_ship.exe", (IntPtr)0x04105320, new int[] { 0x6E5 });
            MessageBox.Show(memory.ReadUInt32(prestigeAddress).ToString());
            //memory.WriteUInt32(address, uint.Parse(prestigeLevel.ToString()));

            // Wins code
            IntPtr winAddress = memory.GetAddress("iw7_ship.exe", (IntPtr)0x04105320, new int[] { 0x30 });
            MessageBox.Show(memory.ReadUInt32(winAddress).ToString());
        }
    }
}


I really don't get whats causing the wrong values since it worked once before. Does anyone here have a idea ?

I would really appreciate any kind of help.


Last edited by d4ne on Fri Dec 09, 2016 6:38 am; edited 1 time in total
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 199

Joined: 25 Jan 2006
Posts: 8518
Location: 127.0.0.1

PostPosted: Thu Dec 08, 2016 11:25 pm    Post subject: Reply with quote

Judging by this:
Code:
IntPtr prestigeAddress = memory.GetAddress("iw7_ship.exe", (IntPtr)0x04105320, new int[] { 0x6E4 });


You are using the code incorrectly. 0x04105320 looks like the full address and not an offset. The code you are using is taking the base address of the given module and adding an offset to it to get the valid address. Your offset is probably just 0x105320 but double check and be sure. You should read what you are doing instead of just copy-pasting code and not understanding it.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
d4ne
How do I cheat?
Reputation: 0

Joined: 06 Dec 2016
Posts: 7

PostPosted: Fri Dec 09, 2016 5:21 am    Post subject: Reply with quote

It can't be wrong since it worked once before. Somehow it returned the real value once but never again.

And the Pointerscan looks like the following:

Address:
145D114B9 = 15269896

Description:
pointerscan result

Type:
Byte

Pointer:
(Checked)

< 6E5 > 145D10DD4 + 6E5 = 145D114B9
"iw7_ship.exe"+04105320 -> 145D10DD4

And here's a screenshot:
gyazo (dot) com/2ab911a596ad6cdbb4567f408bae39f2

So I've tryed to get the address by doing the following:

"iw7_ship.exe"+04105320 + 6E5

Could the wrong result be caused by the return type of the called function since the type of the pointerscan is a byte?

Code:
MessageBox.Show(memory.ReadUInt32(prestigeAddress).ToString());


which calls the following function:

Code:
/// <summary>
/// Reads 32 bit unsigned integer at the address
/// </summary>
/// <param name="address">Memory address</param>
/// <returns></returns>
public uint ReadUInt32(IntPtr address)
{
    byte[] buffer = new byte[4];
    ReadMemory(address, buffer, 4);
    return BitConverter.ToUInt32(buffer, 0);
}
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 199

Joined: 25 Jan 2006
Posts: 8518
Location: 127.0.0.1

PostPosted: Sun Dec 11, 2016 8:37 pm    Post subject: Reply with quote

You certain that the address you found is still working after the game is fully restarted? The pointer you found may not be valid.

As for the return type, you need to only read the amount of data that the value is valid for. If the return of the pointer scanner says its a byte, you should read it as a byte and not as an UInt32.

So after you have done:
Code:
IntPtr prestigeAddress = memory.GetAddress("iw7_ship.exe", (IntPtr)0x04105320, new int[] { 0x6E4 });


Read a single byte with that address instead. With the code you have above, just manually call ReadMemory with a buffer of 1 byte size like this:

Code:

IntPtr prestigeAddress = memory.GetAddress("iw7_ship.exe", (IntPtr)0x04105320, new int[] { 0x6E4 });

var buffer = new byte[1];
ReadMemory(prestigeAddress, buffer, 1);


Then your data you want is in buffer[0].

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
Spiff
How do I cheat?
Reputation: 0

Joined: 20 Oct 2015
Posts: 3

PostPosted: Sun Jan 24, 2021 5:45 am    Post subject: Reply with quote

Hi,

I also use the Farcry 3 classes by Matej Tomčík.
It worked like a charme since the game was 32 bit.
Now, in the last update of the game they changed it to 64 bit and the addresses are also 8 byte values and not 4 bytes any more, so it throws a lot of errors.

Did you manage to get your 64 bit game working?
I already changed the project from x86 to x64.

Also: I cannot find the original class files in the web anymore... and I overwrote mine without making a copy. Rolling Eyes
Does somebody still have the original files anywhere and can sent them to me?

Thanks, have a nice day
Spiff
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 199

Joined: 25 Jan 2006
Posts: 8518
Location: 127.0.0.1

PostPosted: Sun Jan 24, 2021 8:06 pm    Post subject: Reply with quote

Take your pick, it's the same copy-pasta crap on all of these repos:
https://github.com/search?l=C%23&q=%22%28%5C%5C%2B%7C%5C%5C-%29%7B0%2C1%7D%280x%29%7B0%2C1%7D%5Ba-fA-F0-9%5D%7B1%2C%7D%22%3B&type=Code

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites