 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
samuri25404 Grandmaster Cheater
Reputation: 7
Joined: 04 May 2007 Posts: 955 Location: Why do you care?
|
Posted: Sat Jun 14, 2008 12:20 am Post subject: [C#] VirtualQueryEx Returning Weird Results? |
|
|
I was writing a simple page walker in C#, and I've been having it return some odd results.
I've compared my code to that of Cheat Engine--they're quite similar, and the results are different; Cheat Engine runs faster (don't say because I'm managed, there's not that much of a difference, but it's a little noticeable), and has less results.
Oddly, Cheat Engine has the results grouped up, and I think it's the API's doing, but I can't figure out why.
Here's Cheat Engine's code
| Code: |
while (Virtualqueryex (processhandle, pointer(address), mbi, sizeof(mbi)) <> 0) and ((address+mbi.RegionSize)>address) do
begin
setlength(moreinfo,length(moreinfo)+1);
moreinfo[length(moreinfo)-1].address:=dword(mbi.BaseAddress);
moreinfo[length(moreinfo)-1].size:=mbi.RegionSize;
moreinfo[ length(moreinfo)-1 ]. isreadable := (mbi.State = mem_commit) and ((mbi.Protect and page_guard)=0) and ((mbi.protect and page_noaccess)=0);
...
inc(address,mbi.RegionSize);
|
( http://ce.colddot.nl/browser/Cheat%20Engine/formmemoryregionsunit.pas )
Here's mine:
| Code: |
public bool bDumpPages(
out int errorCode)
{
errorCode = 0;
if (hProcess == null) return false;
IntPtr iAddress = siSysInfo.lpMinimumApplicationAddress;
WINAPI.MEMORY_BASIC_INFORMATION mbiBuffer = new WINAPI.MEMORY_BASIC_INFORMATION();
Page pBuffer;
mbiBuffer.RegionSize = siSysInfo.dwPageSize;
while (WINAPI.VirtualQueryEx(
hProcess,
(IntPtr)iAddress,
ref mbiBuffer,
Marshal.SizeOf(mbiBuffer)) != 0
&& ((ulong)iAddress < (ulong)siSysInfo.lpMaximumApplicationAddress))
{
errorCode = Marshal.GetLastWin32Error();
if (errorCode != 0) return false;
pBuffer = getWrapperFromMBI(mbiBuffer);
Pages.Add(pBuffer);
iAddress = (IntPtr)((ulong)iAddress + (ulong)mbiBuffer.RegionSize); //C# doesn't allow addition of IntPtr's
}
WINAPI.CloseHandle(hProcess);
return true;
}
|
_________________
|
|
| Back to top |
|
 |
Estx Expert Cheater
Reputation: 0
Joined: 04 Mar 2008 Posts: 172
|
Posted: Sat Jun 14, 2008 2:04 am Post subject: |
|
|
Use uint instead of ulong. Your addresses wont go past 0xFFFFFFFF. It'll speed it up a tiny bit because it wont have to manage as much memory.
I've also noticed that Cheat Engine returns less information than what my own applications do. Maybe there's something being filtered? I haven't read through C.E's source code though. Other than that, there's nothing wrong with your code. Could be optimized in a few places, but otherwise it works as it should from my perspective.
But as I was saying before, I wrote a Starter Trainer Kit in C# that utilizes my own search function after processing the the pages to see if they're allocated or not then returning results I get more than what I would in C.E. with similar settings. Usually a lot faster than C.E. as well.
Ah well, sorry I couldn't be of help. Dark Byte may be able to help you better on this matter.
|
|
| Back to top |
|
 |
samuri25404 Grandmaster Cheater
Reputation: 7
Joined: 04 May 2007 Posts: 955 Location: Why do you care?
|
Posted: Sat Jun 14, 2008 2:36 am Post subject: |
|
|
| Estx wrote: | | Use uint instead of ulong. Your addresses wont go past 0xFFFFFFFF. It'll speed it up a tiny bit because it wont have to manage as much memory. |
That's actually what I had it as originally; it looped forever with the value being something like 65535.
| Estx wrote: | | I've also noticed that Cheat Engine returns less information than what my own applications do. Maybe there's something being filtered? I haven't read through C.E's source code though. Other than that, there's nothing wrong with your code. Could be optimized in a few places, but otherwise it works as it should from my perspective. |
Well, the way I was picturing it working was quite similar to Cheat Engine's. VQEX is supposed to just take a collection of pages and add them together until a different set of attributes is found.
Something else odd to note is that my lType and Protect fields were coming back as 0. Also, instead of coming back with the MEM_FREE constant, or whatever it was, the State would also come back as 0 sometimes.
As for the optimization, I know. :P
I make rough drafts of code, as I do with writing.
One gets the general outline, tests it, makes sure it works, etc, then puts the finishing touches/optimizations on it. One doesn't really need to worry about it until the end, right?
| Estx wrote: | But as I was saying before, I wrote a Starter Trainer Kit in C# that utilizes my own search function after processing the the pages to see if they're allocated or not then returning results I get more than what I would in C.E. with similar settings. Usually a lot faster than C.E. as well.
Ah well, sorry I couldn't be of help. Dark Byte may be able to help you better on this matter. |
I've had similar experiences. Maybe it's a language thing?
Edit:
Also, just in case anyone was wondering, I did debug and check the System Info stuff. The dwPageSize was 4096, or 0x1000, which is Cheat Engine's default page size.
I forget the lpApplicationMinimum/MaximumAddress or whatever values, but they were both reasonable.
_________________
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 472
Joined: 09 May 2003 Posts: 25869 Location: The netherlands
|
Posted: Sat Jun 14, 2008 6:42 am Post subject: |
|
|
See how fast it is when removing
| Code: |
pBuffer = getWrapperFromMBI(mbiBuffer);
pages.add(pBuffer);
|
it might be a slowdown there
Also, how do you mean a different output? If you keep giving an ever increasing Address given to VirtualQueryEx, you will also get a sorted result. (it goes from lowest address to highest, and no sorting even needed) If your does get changed, then I suggest to turn of sorting. Might be your gui is sorting them in alphanumeric order, which will slow down when adding new items
_________________
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 |
|
 |
samuri25404 Grandmaster Cheater
Reputation: 7
Joined: 04 May 2007 Posts: 955 Location: Why do you care?
|
Posted: Sat Jun 14, 2008 12:19 pm Post subject: |
|
|
| Dark Byte wrote: | See how fast it is when removing
| Code: |
pBuffer = getWrapperFromMBI(mbiBuffer);
pages.add(pBuffer);
|
it might be a slowdown there |
Yeah, I know Generic Lists aren't the fastest things ever, but it doesn't matter much to me.
Edit: Not much of a difference, actually.
| Dark Byte wrote: | | Also, how do you mean a different output? If you keep giving an ever increasing Address given to VirtualQueryEx, you will also get a sorted result. (it goes from lowest address to highest, and no sorting even needed) If your does get changed, then I suggest to turn of sorting. Might be your gui is sorting them in alphanumeric order, which will slow down when adding new items |
I'll try incrementing it. Here are some of my results for Notepad; I don't feel like getting them from CE, since people can do that themselves. Also, the speed isn't very noticeable, and CE has to add stuff to the listbox as well; I'm just wondering if the API is wacking up.
Here's without incrementing:
| Code: |
Base Address: 00010000
Region Size: 00001000
State: MEM_RESERVE
Protection: 0
Page Type: 0
~~~~~
Base Address: 00011000
Region Size: 00010000
State: 0
Protection: 0
Page Type: 0
~~~~~
Base Address: 00021000
Region Size: 00010000
State: 0
Protection: 0
Page Type: 0
~~~~~
Base Address: 00031000
Region Size: 00010000
State: 0
Protection: 0
Page Type: 0
~~~~~
Base Address: 00041000
Region Size: 00002000
State: MEM_RESERVE
Protection: 0
Page Type: 0
~~~~~
Base Address: 00043000
Region Size: 00002000
State: MEM_RESERVE
Protection: 0
Page Type: 0
~~~~~
Base Address: 00045000
Region Size: 00002000
State: MEM_RESERVE
Protection: 0
Page Type: 0
|
Here's my methods for converting the value to the string (for State, Protection and Type)
| Code: |
private string getState(long stateID)
{
switch (stateID)
{
case 0x1000: return "MEM_COMMIT";
case 0x10000: return "MEM_FREE";
case 0x20000: return "MEM_RESERVE";
}
return stateID.ToString("X");
}
private string getProtect(long protectID)
{
switch (protectID)
{
case 0x10: return "PAGE_EXECUTE";
case 0x20: return "PAGE_EXECUTE_READ";
case 0x40: return "PAGE_EXECUTE_READWRITE";
case 0x80: return "PAGE_EXECUTE_WRITECOPY";
case 0x01: return "PAGE_NOACCESS";
case 0x02: return "PAGE_READONLY";
case 0x04: return "PAGE_READWRITE";
case 0x08: return "PAGE_WRITECOPY";
}
return protectID.ToString("X");
}
private string getType(long typeID)
{
switch (typeID)
{
case 0x1000000: return "MEM_IMAGE";
case 0x40000: return "MEM_MAPPED";
case 0x20000: return "MEM_PRIVATE";
}
return typeID.ToString("X");
}
|
Edit:
Not sure if this is what you meant, but I changed the line to this:
| Code: |
iAddress = (IntPtr)((ulong)iAddress + (ulong)mbiBuffer.RegionSize + 1);
|
Same results.
Edit Again:
I was debugging, and realized that I'd forgotten about the Allocation Protect value for MBI.
Something odd, I thought, was this big ass value; I checked MSDN, and it isn't remotely close to what it should be.
| Code: |
AllocationProtect = 0x0000f00000000000
|
From VS.
Another Edit:
I figured out why it doesn't sort; the "AllocationProtect" changes each time.
I'm going to try messing around with my struct definition.
Final Edit:
WOOHOO! I had bad types for the parameters. The MBI is filled with good values now.
_________________
|
|
| Back to top |
|
 |
atom0s Moderator
Reputation: 205
Joined: 25 Jan 2006 Posts: 8587 Location: 127.0.0.1
|
Posted: Sun Jun 15, 2008 12:15 pm Post subject: |
|
|
I had the same issue, mine shows some different results then CE's but compared mine to a few other tools and my results matched those of the other tools. Also, you can obtain the valid max page size using GetSystemInfo() and using the lpMinApplicationAddresss / lpMaxApplicationAddress from the structure for where to start and stop the loop for the pages.
_________________
- Retired. |
|
| Back to top |
|
 |
samuri25404 Grandmaster Cheater
Reputation: 7
Joined: 04 May 2007 Posts: 955 Location: Why do you care?
|
Posted: Sun Jun 15, 2008 12:18 pm Post subject: |
|
|
| Wiccaan wrote: | | I had the same issue, mine shows some different results then CE's but compared mine to a few other tools and my results matched those of the other tools. Also, you can obtain the valid max page size using GetSystemInfo() and using the lpMinApplicationAddresss / lpMaxApplicationAddress from the structure for where to start and stop the loop for the pages. |
Well, after fixing mine up, I have pretty much the same results as CE.
Also, if you didn't notice, I was using the lpMin/MaxAddr values in my scanner.
Edit:
After doing a scan (I wrote a memory scanner that works pretty quickly--about a minute or so tops for an int value, using a generic scanner), I got a few more thousand results than CE. o_O
I played around with CE's settings, and still got like 7k vs. 4xx.
_________________
|
|
| 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
|
|