|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
d4ne How do I cheat? Reputation: 0
Joined: 06 Dec 2016 Posts: 7
|
Posted: Thu Dec 08, 2016 7:35 pm Post subject: Help needed - C# - Memory GetAddress always returnin 0 |
|
|
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 |
|
|
atom0s Moderator Reputation: 199
Joined: 25 Jan 2006 Posts: 8518 Location: 127.0.0.1
|
Posted: Thu Dec 08, 2016 11:25 pm Post subject: |
|
|
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 |
|
|
d4ne How do I cheat? Reputation: 0
Joined: 06 Dec 2016 Posts: 7
|
Posted: Fri Dec 09, 2016 5:21 am Post subject: |
|
|
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 |
|
|
atom0s Moderator Reputation: 199
Joined: 25 Jan 2006 Posts: 8518 Location: 127.0.0.1
|
Posted: Sun Dec 11, 2016 8:37 pm Post subject: |
|
|
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 |
|
|
Spiff How do I cheat? Reputation: 0
Joined: 20 Oct 2015 Posts: 3
|
Posted: Sun Jan 24, 2021 5:45 am Post subject: |
|
|
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.
Does somebody still have the original files anywhere and can sent them to me?
Thanks, have a nice day
Spiff
|
|
Back to top |
|
|
atom0s Moderator Reputation: 199
Joined: 25 Jan 2006 Posts: 8518 Location: 127.0.0.1
|
|
Back to top |
|
|
|
|
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
|
|