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 


memory scanner (slow) help

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
ups2000ups
I post too much
Reputation: 0

Joined: 31 Jul 2006
Posts: 2471

PostPosted: Tue Oct 07, 2008 2:05 am    Post subject: memory scanner (slow) help Reply with quote

im making a small memory editor but the scan is slow
well if i just scan with no result no problem it will be fast but when i get alot of result it will take time

i know the problem is that it take long time to write it to the hardware
thats why i wondering how i should save it in the memory and then save it to a file

there will be no difference if i save the result in a listbox than a txt file it will take the same time

Code:

ThreadId := GetWindowThreadProcessId(readfrom,@ProcessId);
HandleWindow := OpenProcess(PROCESS_ALL_ACCESS,False,ProcessId);

start := strtoint('$'+from.Text);
stop := strtoint('$'+scanto.Text);
valuetofind := strtoint(ScanValue.text);

AssignFile(WriteFile,ExtractFilePath(ParamStr(0))+FirstScanAddressTMP);
Rewrite(WriteFile) ;

  if chooseScan = 0 then begin // if scan for exact value
    while start < stop do begin
      ReadProcessMemory(HandleWindow,Pointer(start),@value2,4,x);
      if value2 = valuetofind then
       WriteLn(WriteFile,inttohex(start,8) + '=' + inttostr(value2));
      start := start+$1;
    end;
  end else // Stop Exact Scan;

_________________
dont complain about my english...
1*1 = 2?


Last edited by ups2000ups on Tue Oct 07, 2008 4:04 am; edited 1 time in total
Back to top
View user's profile Send private message
tombana
Master Cheater
Reputation: 2

Joined: 14 Jun 2007
Posts: 456
Location: The Netherlands

PostPosted: Tue Oct 07, 2008 3:19 am    Post subject: Reply with quote

When writing the file, you're doing: inttohex(start,Cool and also inttostr(value2).
An int takes up 4 bytes, but when you convert it to readable characters like you do it can take up much more. Just save it into the file as an int. Then you can also read it as an int when you open the file, and convert it to a string if nessecary.
Back to top
View user's profile Send private message
ups2000ups
I post too much
Reputation: 0

Joined: 31 Jul 2006
Posts: 2471

PostPosted: Tue Oct 07, 2008 3:30 am    Post subject: Reply with quote

tombana wrote:
When writing the file, you're doing: inttohex(start,Cool and also inttostr(value2).
An int takes up 4 bytes, but when you convert it to readable characters like you do it can take up much more. Just save it into the file as an int. Then you can also read it as an int when you open the file, and convert it to a string if nessecary.


you cant write integer to a text file since it is text only

the the problem isent the variable it is that it take time to write it into the hardware

i would need to save it in the psychical memory while scanning and when done to the hardware

_________________
dont complain about my english...
1*1 = 2?
Back to top
View user's profile Send private message
tombana
Master Cheater
Reputation: 2

Joined: 14 Jun 2007
Posts: 456
Location: The Netherlands

PostPosted: Tue Oct 07, 2008 4:07 am    Post subject: Reply with quote

About the speed. You're using ReadProcessMemory on every single byte of memory. ( start := start+$1; )
What you need to do is call RPM once on every section or so, and read that into a buffer. Then compare every byte of that buffer with what you're searching for.
And you could write int's to a text file but then you won't be able to view it with notepad or so.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 475

Joined: 09 May 2003
Posts: 25975
Location: The netherlands

PostPosted: Tue Oct 07, 2008 5:17 am    Post subject: Reply with quote

yes, just read huge chunks of memory and then scan through that block
A ReadProcessMemory call takes time, so do as little of those calls as you can

Thats why you use virtualqueryex to find out which memory blocks are readable


Same for write operations. Instead of immediately writing to disk store the results in memory and only when full call the option to write. E.g have an array of 8196 dwords and when full write that.

I also don't recommend saving it as text but just as binary. This can later on help you make finding stuff faster. (No need to parse each single address back to a value)

Or (i know, it's unacceptable, but still):
look here: http://ce.colddot.nl/browser/Cheat%20Engine/memscan.pas

_________________
Tools give you results. Knowledge gives you control.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
tombana
Master Cheater
Reputation: 2

Joined: 14 Jun 2007
Posts: 456
Location: The Netherlands

PostPosted: Tue Oct 07, 2008 6:47 am    Post subject: Reply with quote

Yes I think CE's way is the fastest:
First VirtualQueryEx to find out the regions and make a list of those.
Then do ReadProcessMemory on every region.
After every region you should probably search for the desired value. If you first want to do all the RPM's and then search you'll need to allocate a lot of memory I guess.
Then when you've got a list of results write them to the file at once. (as binary)

It's probably even faster to have a dll injected into the process. Then tell the dll to search for a value and then the dll can either write the results to a file or give them back to your application. This is what hyperscan does in CE right?

Tombana
Back to top
View user's profile Send private message
ups2000ups
I post too much
Reputation: 0

Joined: 31 Jul 2006
Posts: 2471

PostPosted: Tue Oct 07, 2008 8:19 am    Post subject: Reply with quote

thanks Smile i have learned more in the past 3 days then i did for 2 years i think Rolling Eyes

Dark Byte there is just one thing i dont get

if i would save it as binary how do i read it then? should i make a function that convert binary to the addresses and values and then put them into my ct? or is there an easier way?

_________________
dont complain about my english...
1*1 = 2?
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 475

Joined: 09 May 2003
Posts: 25975
Location: The netherlands

PostPosted: Tue Oct 07, 2008 8:31 am    Post subject: Reply with quote

binary is just the way the computer stores values so no need for any conversion at all. (Only need to convert it to text using inttohex when displaying it on the screen, but internally it's just normal datatypes)
Just read the contents of the file into an array or a single dword. (if you care about speed, and your harddisk, go for an array)


let's say you have an array of dwords (e.g addresslist)
then just save addresslist as a block of bytes instead of converting it. And when loading it back you can also just load it back into memory without having to convert the text into bytes (so no need for a strtoint('$'+string))

It will require a slightly different way of filehandling though
e.g instead of usuign a textfile use a TFilestream or a normal "file" and then "Rewrite(WriteFile,1)" and using BlockRead/BlockWrite to read from it.

I recommend using TFileStream though, it makes the code more readable and still fast enough

_________________
Tools give you results. Knowledge gives you control.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
nog_lorp
Grandmaster Cheater
Reputation: 0

Joined: 26 Feb 2006
Posts: 743

PostPosted: Thu Oct 09, 2008 2:48 am    Post subject: Reply with quote

I'm confused. You say
Quote:
there will be no difference if i save the result in a listbox than a txt file it will take the same time
. That is false. Writing to a file takes orders of magnitude longer than writing to memory, unless you have used up all the available memory and are killing the swap space.
_________________
Mutilated lips give a kiss on the wrist of the worm-like tips of tentacles expanding in my mind
I'm fine accepting only fresh brine you can get another drop of this yeah you wish
Back to top
View user's profile Send private message
ups2000ups
I post too much
Reputation: 0

Joined: 31 Jul 2006
Posts: 2471

PostPosted: Thu Oct 09, 2008 4:08 am    Post subject: Reply with quote

nog_lorp wrote:
I'm confused. You say
Quote:
there will be no difference if i save the result in a listbox than a txt file it will take the same time
. That is false. Writing to a file takes orders of magnitude longer than writing to memory, unless you have used up all the available memory and are killing the swap space.


if i write it into a file it take like 1 min
if i write it into a listbox it will take unknown time but alot and then you will get an error "out of memory" or something since you could find over 3k addresses and they arent made to handle so much

so even if it is a little bit faster i wont be able to save all results that way

i will test the thing darkbyte sade when i get time Rolling Eyes

_________________
dont complain about my english...
1*1 = 2?
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 475

Joined: 09 May 2003
Posts: 25975
Location: The netherlands

PostPosted: Thu Oct 09, 2008 9:17 am    Post subject: Reply with quote

about the found results,
CE doesn't actually put them all into the listbox.
The listbox just gets set how many lines big it should be so itr creates a valid scrollbox on the right, and then on scrolls it fetches only the items that are visible in the listbox (from first line visible to last line visible) and draws them on it

thats why when you have a huge list and scroll around you can see the harddisk led go up. (ce does cache in blocks of 1000 addresses so only on big scrollmovements it's noticable)
That's also why I use a addressfile in dword format, because the start of the needed address range can be found using (4*firstvisibleitemnr) instead of reading through each line until you've counted the correct number of lines

_________________
Tools give you results. Knowledge gives you control.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
tombana
Master Cheater
Reputation: 2

Joined: 14 Jun 2007
Posts: 456
Location: The Netherlands

PostPosted: Thu Oct 09, 2008 9:23 am    Post subject: Reply with quote

Dark Byte wrote:
about the found results,
CE doesn't actually put them all into the listbox.
The listbox just gets set how many lines big it should be so itr creates a valid scrollbox on the right, and then on scrolls it fetches only the items that are visible in the listbox (from first line visible to last line visible) and draws them on it

So does CE do the drawing manually like when it receives a WM_PAINT message? I know it's in delphi and there you don't have to handle the window messages yourself, but did you write your own drawing function?
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 475

Joined: 09 May 2003
Posts: 25975
Location: The netherlands

PostPosted: Thu Oct 09, 2008 9:50 am    Post subject: Reply with quote

It's basically just a canvas.textout(x,y,text); (that's calling the windows api ExtTextOut)

In this case i'm only using a customdata listview and the only ownerdraw part is where I set the color of the canvas font to green or black depending if it's inside a module or not.

When using ondata it sends a request for each single item in the list where the data is requested for (e.g drawn) , which limits the processing a lot since it only has to read the memory of the visible items and only has to check if the visible items are inside a module. If it had to do that for a million addresses instead of only 20 then it would take several seconds to update each time

_________________
Tools give you results. Knowledge gives you control.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
tombana
Master Cheater
Reputation: 2

Joined: 14 Jun 2007
Posts: 456
Location: The Netherlands

PostPosted: Fri Oct 10, 2008 1:58 am    Post subject: Reply with quote

That's so clever Very Happy
So when you would do this in 'normal' c++, so just win32api, you would create a listview with the 'ownerdraw' option set. Then when you receive a WM_PAINT you check what items are inside the visible region of the listbox and then call ExtTextOut with the correct color and stuff set.
I'm not sure about the ondata part. Is that a window message you receive?
Thanks,
Tombana
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 475

Joined: 09 May 2003
Posts: 25975
Location: The netherlands

PostPosted: Fri Oct 10, 2008 5:25 pm    Post subject: Reply with quote

ondata is based on a windows message after having been processed heavily by filters and what not (checked in the VCL sourcecode)

messages involved: CDDS_ITEMPREPAINT , CDDS_ITEMPOSTPAINT, CDDS_ITEMPREERASE, CDDS_ITEMPOSTERASE, LVN_GETDISPINFO

I use delphi because I hate gui coding a lot

_________________
Tools give you results. Knowledge gives you control.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming 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