 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
maxmadx How do I cheat?
Reputation: 0
Joined: 22 May 2012 Posts: 3
|
Posted: Sat Dec 01, 2012 9:26 pm Post subject: C# - RPM iterations slow as hell with this method! Solution? |
|
|
I have been working on this for months and although it is finished it is too slow and therefore not practical to use This is not a cheat as such, I am using it to read the values stored in a grid of 200x200 boxes. As an example, the values in the first 3 boxes on the top row were set as: 1, 0, 1. Using cheat-engine with type set as 'array of bytes', the following data is presented -setting length as '10'.:
01 00 04 00 00 00 04 44 01 00
The values for each box are 4 bytes apart as shown above in the data structure.
Currently, I am using a trainer class I found on this forum to call the read process memory function (byte) in iteration adding each result to a List which is later converted to an array (representing the first row), and this is repeated for each row of the grid until I have an array for each row in the grid (effectively creating a local snapshot of the grid at any time this is performed. e.g. array1{1,0,1} could be produced calling the class 3 times capturing a row of 3 boxes.
Because I have to read the entire grid, it means I have to call the function 40,000 (200x200) times! which delays the process by up to 30 seconds. Seeing how fast cheat-engine can read millions of addresses I am sure there is a much faster way to achieve this.
Here is the function being called (sorry I couldn't find the post again to give credits). You can see that the ReadProcessMemoryByte value is 2 which is to read the integer value. I thought I could change this to 1,000 which would read the 200 boxes (including 4 byte separations), and then iterate through the big long number cutting out each 4th number (if that makes sense) locally. 1 readprocessmemory of 1,000 bytes should be a hell of a lot faster than 1,000 readprocessmemory calls right?! But No matter what I change this to it only shows '1' in the above example.
| Code: | public static byte ReadPointerByte(string EXENAME, int Pointer, int[] Offset)
{
byte Value = 0;
checked
{
try
{
Process[] Proc = Process.GetProcessesByName(EXENAME);
if (Proc.Length != 0)
{
int Bytes = 0;
int Handle = OpenProcess(PROCESS_ALL_ACCESS, 0, Proc[0].Id);
if (Handle != 0)
{
foreach (int i in Offset)
{
ReadProcessMemoryInteger((int)Handle, Pointer, ref Pointer, 4, ref Bytes);
Pointer += i;
}
ReadProcessMemoryByte((int)Handle, Pointer, ref Value, 2, ref Bytes);
CloseHandle(Handle);
}
}
}
catch
{ }
}
return Value;
} |
I would be very grateful to ANYONE who has more information.
[/code]
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25833 Location: The netherlands
|
Posted: Sat Dec 01, 2012 9:53 pm Post subject: |
|
|
ReadProcessMemory calls are slow.
Imagine it is programmed like this
| Code: |
Sleep(10000000000000
Copy(destination,source,size)
Return
|
So try to limit the number of calls to readprocessmemory as much as possible. Either by reading all the processmemory first using as big blocks as you can, or at least cache all your reads to 4KB blocks that contain the full page of the blocks you've read, and always first lookup if that block has been cached or not, and only if you have to call RPM
And the reason changing the 2 to something higher doesn't work is because the rest of your code hasn't been designed to work with the extra data
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
maxmadx How do I cheat?
Reputation: 0
Joined: 22 May 2012 Posts: 3
|
Posted: Sat Dec 01, 2012 10:03 pm Post subject: |
|
|
| Dark Byte wrote: | ReadProcessMemory calls are slow.
Imagine it is programmed like this
| Code: |
Sleep(10000000000000
Copy(destination,source,size)
Return
|
So try to limit the number of calls to readprocessmemory as much as possible. Either by reading all the processmemory first using as big blocks as you can, or at least cache all your reads to 4KB blocks that contain the full page of the blocks you've read, and always first lookup if that block has been cached or not, and only if you have to call RPM
And the reason changing the 2 to something higher doesn't work is because the rest of your code hasn't been designed to work with the extra data |
Hi,
The speed increase advice sounds promising. The increase of '2' to '1000' was what I am hoping to accomplish by increasing the RPM block of code and just read once. I might be a little too beginner to implement a solution based on the general guidance, can you recommend any sources of learning to properly accomplish the steps you recommended? I posted some questions on stackoverflow and have not got anywhere since july unfortunately.
Just to add that the grid updates every few seconds, so I am constantly needing to update my numbers.
btw, here is the vastly reduced testing code I wrote to display the result of changing '2' to a higher number (I created this simpler project to avoid complications with my other code and to simply test if I could read a bigger block of memory and see how easy it is to manipulate after being read):
with a grid of: 1,0,1 as talked about in the last post:
//some code at start to RPM the start of the structure. then:
X1.Add(ValueX); // Add read byte to list
byte[] X1ToInt = X1.ToArray(); //convert to array
int[] MYConvertedBytes = X1ToInt.Select(x => (int)x).ToArray();//convert to int array
string TestString = MYConvertedBytes[0].ToString();//convert to string
label1.Text = TestString; //display
Leaving bytes length as '2' shows value '1' in the text label (form).
Changing it to another higher number still shows '1'. Then when the number is too high, maybe over 150 then there is an exception. I have verified that the '1' displayed is from the memory location I am targeting and not a miscellaneous byte that the RPM code produces.
|
|
| Back to top |
|
 |
atom0s Moderator
Reputation: 205
Joined: 25 Jan 2006 Posts: 8587 Location: 127.0.0.1
|
Posted: Sun Dec 02, 2012 2:37 pm Post subject: |
|
|
You're better off not using classes for reading/writing memory that you find online. Most of them are poor implementations of the API in C# with a zillion wrappers that are unneeded.
Another thing, you already obtained the process using Process.GetProcessesByName, you do not need OpenProcess. The Process class already exposes a fully qualified handle that you can use with the API.
| Code: |
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
[In, Out] byte[] lpBuffer,
UInt32 nSize,
ref IntPtr lpNumberOfBytesRead
);
var procs = Process.GetProcessesByName( "file.exe" );
var buffer = new byte[2048];
var read = new IntPtr(0);
ReadProcessMemory( procs[0].Handle, lpAddress, buffer, (uint)buffer.Length, ref read );
|
This is a small example, without error checking just to show you how to do things with a bigger buffer. This will read 2048 bytes at once.
_________________
- Retired. |
|
| Back to top |
|
 |
maxmadx How do I cheat?
Reputation: 0
Joined: 22 May 2012 Posts: 3
|
Posted: Mon Dec 03, 2012 1:37 pm Post subject: |
|
|
| Wiccaan wrote: | You're better off not using classes for reading/writing memory that you find online. Most of them are poor implementations of the API in C# with a zillion wrappers that are unneeded.
Another thing, you already obtained the process using Process.GetProcessesByName, you do not need OpenProcess. The Process class already exposes a fully qualified handle that you can use with the API.
| Code: |
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
[In, Out] byte[] lpBuffer,
UInt32 nSize,
ref IntPtr lpNumberOfBytesRead
);
var procs = Process.GetProcessesByName( "file.exe" );
var buffer = new byte[2048];
var read = new IntPtr(0);
ReadProcessMemory( procs[0].Handle, lpAddress, buffer, (uint)buffer.Length, ref read );
|
This is a small example, without error checking just to show you how to do things with a bigger buffer. This will read 2048 bytes at once. |
Hey thanks for this, I will try it out at the end of next week. Thanks again.
|
|
| 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
|
|