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] About Memory Scanner

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
porring09
Newbie cheater
Reputation: 0

Joined: 11 Feb 2014
Posts: 11

PostPosted: Sun Aug 03, 2014 3:03 am    Post subject: [Help] About Memory Scanner Reply with quote

Hi sir(s) im still working on my Memory Scanner Using C++ and VB.net

But Still my problem are the same in C++ and VB.net

in C++ i use DevC++ and i also use VC++ 2008 but no luck.
They are still Slow scanning the Process Memory.

and in VB.net 2008 is much slower than C++.

I search and read in some forums, i gather more and more info just to make it fast. But still no luck.

Please is anyone can help me?

I use VirtualQueryEx() to know if the Current Page is READABLE and WRITABLE , ReadProcessMemory() for Reading the content of the Whole Region. I just read some Thread/Topic here and i get curious again.

Here are some new things for me that i hope there are someone can answer and help me out. i search in google but no one knows. only the definitions but no examples or any kind of more better explanation.

1. What is kernel mode
2. how do i make my application run in kernel mode.
3. What is Memory Mapping , it is Alternative for VirtualQueryEx?
4. How do i implement Memory Mapping in this Program?
5. What is the Proper way of Storing the Address?
A. Read >> Compare >> Write line the Address in a File
B. Dump Each Region in one file and Obtain each Region base Address and Size >> Then Read the PAGE Info(RegionSize , RegionBaseAddress) while reading the Dump File then do Read >> Compare >> Write Line the Address in a File.
C. Both A and B are not Good.



I would like to put more info , because i really want to learn more.

Here are some WINAPI Functions i use do to the Stuff.

OpenProcess
VirtuaQueryEx
ReadProcessMemory
WriteProcessMemory

Another thing.

6. It is better if i learn Assembly Language? or just leave it and use High Level Programming Languages like C++?
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 470

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

PostPosted: Sun Aug 03, 2014 3:38 am    Post subject: Reply with quote

1: Kernelmode is the operating system's internal execution mode. It has access to ring0 instructions.
See it like an injected dll that runs in every single process at the same time

2: You design it from scratch using the driver toolset provided by microsoft and buying a certificate that costs more than $100 a year
Keep in mind that kernelmode can not do gui

3: Memory mapping is a method to lazily read a file or to share memory between processes.
memory regions need to be allocated explicitly to be used for memory mapping

4: you don't as you need to hook all memory allocations before the target even runs

5: binary form (so not text) and write them in blocks (so don't write 4 bytes at a time)

6: it helps with gamehacking but it will not speed up the scan

_________________
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
View user's profile Send private message MSN Messenger
porring09
Newbie cheater
Reputation: 0

Joined: 11 Feb 2014
Posts: 11

PostPosted: Sun Aug 03, 2014 3:48 am    Post subject: Reply with quote

Thank you sir for a quick reply , Thank you very much .

So the Correct Procedure is just dump all the whole committed memory used by the target process as binary e.g Region Size 4096 , 65536, etc then Read the File depend on the size of the Type e.g 4 bytes? isn't it?

may i ask a favor sir please? may can you give me an example of memory mapping instead of using VirtualQueryEx? i search about memory mapping but google keeps giving me MSDN File Mapping ,
Creating a File Mapping Object
Creating a File View
Sharing Files and Memory
Reading and Writing From a File View
Closing a File Mapping Object
File Mapping Security and Access Rights
Using File Mapping

is this the thing that i needed?

I want to make it Right. Please sir.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 470

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

PostPosted: Sun Aug 03, 2014 3:58 am    Post subject: Reply with quote

As i said, filemapping is completely useless for memory scanning
Anyhow,, it is exactly as the msdn says, but you give it a file handle of 0 when creating a file mapping so it'll be in memory instead of a file. And then that memoryblock you just created can be shared with other processes(so it's useless as that memoryblock must be created in the target process and then actually used by it)


http://cheat-engine.googlecode.com/svn/trunk/Cheat%20Engine/sharedMemory.pas is an implementation of filemapping to facilitate shared memory (only useful for writing debug info)

And you don't dump all the committed memory to a file, you read it, scan through it,and then overwrite it with another block.
Even for an unknown initial value scan i don't write it to disk until after the scan is done and the user has done a next scan

In short, keep disk access and gui access to a minimum. If you can get rid of those completely that's even better

_________________
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
View user's profile Send private message MSN Messenger
porring09
Newbie cheater
Reputation: 0

Joined: 11 Feb 2014
Posts: 11

PostPosted: Sun Aug 03, 2014 4:10 am    Post subject: Reply with quote

Ah, i just make my Thread Priority to highest , i mean like multi-Threading
the main Thread in GUI , i should make the Priority to lowest then in the Scanning event Thread i should make it Highest then Turn Back to main Thread After Scanning then make the main Thread's priority to Normal again?

Sir can i post my code , therefore you where able to check-out what should i put , change, and remove in my code? i hope it is ok for you sir. im a newbie sorry for my bad English.

And one thing sir. i don't get the "overwrite it with another block"?! what does it mean? Sad should i Overwrite the same copy of memory in the scanned memory? and should i need to change their Protection? or just leave them?
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 470

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

PostPosted: Sun Aug 03, 2014 4:30 am    Post subject: Reply with quote

I don't have time to check a full sourcecode

Anyhow, with overwriting the block of memory i mean that you preallocate a block of memory that can fit the biggest memoryblock you're going to read.
And after each read/scan reuse that same block without freeing/allocating again

Same for the results. Write them to a block of memory, and when full write to disk and continue in that block from the start

And priorities usually have not much effect

Anyhow, check yourself where your bottlenecks are. E.g do a scan with no writing of results and see if that greatly increases the scan, or not at all.

_________________
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
View user's profile Send private message MSN Messenger
porring09
Newbie cheater
Reputation: 0

Joined: 11 Feb 2014
Posts: 11

PostPosted: Sun Aug 03, 2014 4:53 am    Post subject: Reply with quote

Thank you Sir Smile

I just new that the VirtualAlloc is useful, i should study first What is the use and how do i use that stuff. And about without Scan Result, it makes the loop fast but the problem is , i don't know how to allocate a block of memory then Use/Reuse it to store value , addresses , without dumping it to file.

I just figure out that CE dump a list of Addresses that is being scanned and use as result and also use for Undo Scan.

Thank you sir. thank you very much,

I'm still posting my code , it is ok for me if you did't reply as fast but i hope if you have much time., you would read and help me . Thank you again sir Smile


//==========================
#ifndef H_MemoryScanner
#define H_MemoryScanner

#define _READABLE (PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY)
#define _READABLE_A (PAGE_EXECUTE_WRITECOPY | PAGE_WRITECOPY | PAGE_READWRITE)
#define _PROTECTION (MEM_PRIVATE | MEM_MAPPED | MEM_IMAGE)

#include <windows.h>
#include <iostream>
#include <fstream>
#include <string>

using namespace std;



enum ScanType{
ExactValue ,
IncreaseValue ,
DecreaseValue ,
IncreseValueBy ,
DecreaseValueBy ,
BetweenValue ,
UnknownInitialValue
}ScanStyle; // End of struct ScanType



template<class Type>
class Scanner{

public:
Scanner();
Scanner(HANDLE hProcess , MEMORY_BASIC_INFORMATION mbi , DWORD START_RANGE = 0x00000000 , DWORD END_RANGE = 0x7FFFFFFF);
~Scanner();
void Option(bool v_ReadOnly = false , bool v_Executable = true , bool v_writeCopy = true , unsigned int stepSize = 4);
void FirstScan(const Type& VALUE = NULL , const Type& OTHER_VALUE = NULL );
void NextScan(const Type& VALUE = NULL , const Type& OTHER_VALUE = NULL);
void WriteProcess(const DWORD tAddress , const Type VALUE);
void ReadProcess(const DWORD tAddress);
void setScanType(ScanType scanStyle);
void cancelScan();
unsigned int getPageCount();
unsigned int getRegionSize();
unsigned int getBaseAddress();

private:
// void printProperties(); unused
bool isEqual(Type VALUE , Type toValue);
bool isBetween(Type VALUE , Type from , Type to );
bool isIncresed(Type VALUE , Type before );
bool isDecresed(Type VALUE , Type before );
bool isIncreasedBy(Type VALUE , Type increment );
bool isDecresedBy(Type VALUE , Type decrement );

struct Property{

HANDLE _PROCESS_HANDLE;
MEMORY_BASIC_INFORMATION _MBI;
DWORD _START_RANGE;
DWORD _END_RANGE;
// DWORD *_CACHE_SCANNED; For now it is unused
// DWORD *_CACHE_SCANNED_VALUE; For now it is unused
unsigned int _STEP_SIZE;
unsigned int _BYTE_SIZE;
unsigned int _REGION_SIZE;
unsigned int _PAGE_COUNT;
unsigned int _MAX_MEMORY_BLOCK;
ScanType scanningStyle;
bool _VREAD_ONLY;
bool _VEXREAD;
bool _VEXECUTABLE;
bool _VWRITECOPY;
bool _CANCEL_SCAN;
LPVOID _BASE_ADDRESS;

};

Property props;
}; // End of Class Scanner


template<class Type>
Scanner<Type>::Scanner(){
// Default Constructor of Scanner Class
props._PROCESS_HANDLE = NULL;
props._START_RANGE = 0x00000000;
props._END_RANGE = 0x7FFFFFFF;
props._BYTE_SIZE = sizeof(Type);
props._CANCEL_SCAN = false;

} // End of Default Constructor

template<class Type>
Scanner<Type>::Scanner(HANDLE hProcess , MEMORY_BASIC_INFORMATION mbi , DWORD START_RANGE , DWORD END_RANGE){
/*
This Function is Use as CONSTRUCTOR of the Scanner Class
Initialize Each private member of the Class
Revision : 0
*/

props._PROCESS_HANDLE = hProcess;
props._MBI = mbi;
props._START_RANGE = START_RANGE;
props._END_RANGE = END_RANGE;
props._BYTE_SIZE = sizeof(Type);
props._BASE_ADDRESS = 0;
props._CANCEL_SCAN = false;

// Initialize MBI
VirtualQueryEx(props._PROCESS_HANDLE , (void *)props._BASE_ADDRESS, &props._MBI, sizeof(props._MBI));
// Get the PAGE_COUNT and TOTAL Readable Address in the Process Memory

{ // Start Block of Getting the PAGE_COUNT and TOTAL REGION SIZE
unsigned int pageCount = 0;
unsigned int BytesReadable = 0;
unsigned int start = 0, end = 0;
LPVOID baseAddress = props._BASE_ADDRESS;
while(VirtualQueryEx(props._PROCESS_HANDLE , (void *)baseAddress, &props._MBI, sizeof(props._MBI))){

start = (unsigned)props._MBI.BaseAddress;
end = (unsigned)props._MBI.BaseAddress + props._MBI.RegionSize;
if(props._MBI.State & MEM_COMMIT){
if(props._MBI.AllocationProtect & _READABLE){
pageCount++;
BytesReadable += props._MBI.RegionSize;
}
}
baseAddress = reinterpret_cast<void*>(end);
}

props._PAGE_COUNT = pageCount;
props._REGION_SIZE = BytesReadable;
} // END OF TEMP BLOCK

} // End of Constructor of Class Scanner

template<class Type>
Scanner<Type>::~Scanner(){
// Default Destructor of Class Scanner
Property *p;
p = &props;
delete p;
}// End of Destructor of Class Scanner

template<class Type>
void Scanner<Type>::Option(bool v_ReadOnly , bool v_Executable , bool v_writeCopy , unsigned int stepSize){
props._VREAD_ONLY = v_ReadOnly;
props._VEXECUTABLE = v_Executable;
props._VWRITECOPY = v_writeCopy;
props._STEP_SIZE = stepSize;
} // End of Option Function of Class Scanner

template<class Type>
void Scanner<Type>::FirstScan(const Type& VALUE , const Type& OTHER_VALUE){
// This is use to Do a First Scan in the Process Memory Address
unsigned int _START = 0;
unsigned int _END = 0;
unsigned int _TOTAL_READ = 0;
unsigned int _TOTAL_FOUND = 0;
Type _READ;
unsigned char _out[1];
LPVOID baseAddress;
props._BASE_ADDRESS = reinterpret_cast<void *>(props._START_RANGE);
baseAddress = props._BASE_ADDRESS;

ofstream ofile("FIRST.SCAN" , ios::out);

Sleep(100);

while(VirtualQueryEx(props._PROCESS_HANDLE , (void *)baseAddress , &props._MBI , sizeof(props._MBI))){
_START = (unsigned)props._MBI.BaseAddress;
_END = (unsigned)props._MBI.BaseAddress + props._MBI.RegionSize;

if(props._MBI.State == MEM_COMMIT){
// Make a switch statement to choose what to view and not
switch(props._MBI.AllocationProtect){
case PAGE_READONLY:
if(props._VREAD_ONLY){
goto scanRegion;
}else{goto skipRegion;}
case PAGE_EXECUTE:
if(props._VEXECUTABLE){
goto scanRegion;
}else{goto skipRegion;}
case PAGE_EXECUTE_READ:
case PAGE_READWRITE:
case PAGE_WRITECOPY:
case PAGE_EXECUTE_READWRITE:
case PAGE_EXECUTE_WRITECOPY:
scanRegion:
_out = new unsigned char[ props._MBI.RegionSize];
sampleclass sc;
sc.ReadProcessMemory(props._PROCESS_HANDLE, (void *)props._MBI.RegionSize, &_out, &props._MBI.RegionSize , 0);
// if(_READ != VALUE){goto bypassAddress;}
// switch for Scanning Style
cout << props._MBI.RegionSize << "\n";
ofile << _out << "\n";

} // End of Switch
} // End of IF _MBI.State

skipRegion:
baseAddress = reinterpret_cast<void*>(_END); // Move to Next Readable Region

} // End of While Loop [VirtualQueryEx]
ofile.close();
cout << "\nTotal Read:" << _TOTAL_READ << "\nTotal Found:" << _TOTAL_FOUND << "\n";
} // End of Function FirstScan of Class Scanner

template<class Type>
void Scanner<Type>::NextScan(const Type& VALUE , const Type& OTHER_VALUE ){

// Declare Temporary Memory Block to Store new Set of addreses
unsigned int _TOTAL_READ = 0;
unsigned int _TOTAL_FOUND = 0;
Type _READ = 0;
LPVOID baseAddress = reinterpret_cast<void *>(0x0); // Initialization of baseAddress
DWORD ptr;
ifstream ifile("FIRST.SCAN" , ios::in);
ofstream ofile("NEXT.SCAN" , ios::out);

string line;
while(getline(ifile, line)){
if(line.length() <= 0){break;}
ptr = strtol(line.c_str() ,0 ,0);
baseAddress = reinterpret_cast<void *>((unsigned)ptr);
if(VirtualQueryEx(props._PROCESS_HANDLE , baseAddress , &props._MBI , sizeof(props._MBI)) ){
ReadProcessMemory(props._PROCESS_HANDLE , (void *)ptr , &_READ , sizeof(Type) , 0 );
// switch for Scanning Style
switch(ScanStyle){
case ExactValue:
{
if(isEqual(VALUE , _READ)){
ofile << reinterpret_cast<void *>(baseAddress) << "\n";
cout << reinterpret_cast<void *>(baseAddress);
_TOTAL_FOUND++;
goto bypassAddress;
}
}break;
case IncreaseValue:
{

}break;
case DecreaseValue:
{

}break;
case IncreseValueBy:
{

}break;
case DecreaseValueBy:
{

}break;
case BetweenValue:
{
if(isBetween(_READ , VALUE , OTHER_VALUE)){

_TOTAL_FOUND++;
goto bypassAddress;
}
}break;
case UnknownInitialValue:
{

}break;
} // End of Switch
bypassAddress:
baseAddress = reinterpret_cast<void *>((unsigned)ptr) ;// Set new baseAddress to skip unlisted Address from the Region
// End of If [READ == VALUE]
_TOTAL_READ++;
} // End of While Block [VirtualQueryEx]
}
cout << "\nTotal Read:" << _TOTAL_READ << "\nTotal Found:" << _TOTAL_FOUND << "\n";
ofile.close();
ifile.close();
system("ren FIRST.SCAN tempfileF.stg");
system("ren NEXT.SCAN FIRST.SCAN");
system("ren tempfileF.stg NEXT.SCAN");
} // End of NextScan Function of Scanner Class

template<class Type>
void Scanner<Type>::WriteProcess(const DWORD tAddress , const Type VALUE){
if(WriteProcessMemory(props._PROCESS_HANDLE, (void *)tAddress , &VALUE , sizeof(Type), 0)){
cout << "\nWrite Success!\n" ;
}else{
cout << "\nWrite Failed!\n" ;
}
}

template<class Type>
void Scanner<Type>::ReadProcess(const DWORD tAddress){
Type __V;
if(ReadProcessMemory(props._PROCESS_HANDLE, (void *)tAddress , &__V , sizeof(Type), 0)){
cout << __V << "\n";
}else{
cout << "\nWatch Failed!\n" ;
}
}

template<class Type>
void Scanner<Type>::cancelScan(){
// Use to Cancel Scan Event
props._CANCEL_SCAN = true;
} // End of cancelScan Function

template<class Type>
unsigned int Scanner<Type>::getPageCount(){
return props._PAGE_COUNT;
} // End of getPageCount Function

template<class Type>
unsigned int Scanner<Type>::getRegionSize(){
return props._REGION_SIZE;
} // End of getRegionSize Function

template<class Type>
unsigned int Scanner<Type>::getBaseAddress(){
return props._BASE_ADDRESS;
} // End of getBaseAddress Function

template<class Type>
void Scanner<Type>::setScanType(ScanType scanStyle){
ScanStyle = scanStyle;
}
// ======================= END OF PUBLIC FUNCTIONS ===================== //
template<class Type>
bool Scanner<Type>::isEqual(Type VALUE , Type toValue){
return (VALUE == toValue);
}

template<class Type>
bool Scanner<Type>::isBetween(Type VALUE , Type from , Type to ){
return ((VALUE >= to) && (VALUE <= from));
}
template<class Type>
bool Scanner<Type>::isIncresed(Type VALUE , Type before){
return (VALUE > before);
}

template<class Type>
bool Scanner<Type>::isDecresed(Type VALUE , Type before){
return (VALUE < before);
}

template<class Type>
bool Scanner<Type>::isIncreasedBy(Type VALUE , Type increment ){
return ((VALUE - increment) == VALUE);
}

template<class Type>
bool Scanner<Type>::isDecresedBy(Type VALUE , Type decrement ){
return ((VALUE + decrement) == VALUE);
}
// ======================= END OF PRIVATE FUNCTIONS ==================== //


#endif


//==========================

Sorry about my Messy code.
Back to top
View user's profile Send private message
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