Page 1 of 1

Get the memory range and size available to your process!

Posted: Thu Sep 02, 2010 10:25 pm
by Rescator
Thanks to Kwaï chang caïne for asking the question that inspired me to find out if this information was actually available or not! :)

Code: Select all

EnableExplicit

;GlobalMemoryStatusEx at http://msdn.microsoft.com/en-us/library/aa366589%28VS.85%29.aspx
;GetSystemInfo at http://msdn.microsoft.com/en-us/library/ms724381.aspx

Import "kernel32.lib"
	GlobalMemoryStatusEx.l(*lpBuffer)
EndImport

Define meminfo.MEMORYSTATUSEX,si.SYSTEM_INFO,maxvmemsize.q,*minaddress,*maxaddress

meminfo\dwLength=SizeOf(MEMORYSTATUSEX)
If GlobalMemoryStatusEx(meminfo)
	maxvmemsize=meminfo\ullTotalVirtual
	
	GetSystemInfo_(si)
	*minaddress=si\lpMinimumApplicationAddress
	*maxaddress=si\lpMaximumApplicationAddress
	
	Debug "Memory range of this process:"
	Debug Str(maxvmemsize)+" Bytes range."
	Debug "$"+Hex(*minaddress)+" start address.."
	Debug "$"+Hex(*maxaddress)+" end address."
EndIf
PS! On my system with a normal x86 PB program I get a range starting at $10000 and up to $7FFEFFFF. Which is basically 2GB minus 128KB (I wonder what is stealing that addresses? BIOS? VFGA? Soundcard?)

If the exe was compiled as Large Address Aware it would probably be closer to 3GB range since I'm running a x64 windows OS.

And if I compile as a x64 program I get:
Memory range of this process:
8796092891136 Bytes range.
$10000 start address..
$7FFFFFEFFFF end address.

Which is close to 8TB minus a little.

Re: Get the memory range and size available to your process!

Posted: Thu Sep 02, 2010 10:53 pm
by PB
Looks good! Can this be tweaked to get the same info from other processes?
I've been trying to make a special trainer for years but have never been able
to get the start/end memory addresses of other processes.

Re: Get the memory range and size available to your process!

Posted: Thu Sep 02, 2010 11:22 pm
by Rescator
Sure, the info is on MSDN somewhere.
But. If it's a more complicated trainer, you already have the injection working right?
In that case simply run this code inside that process.

But if not using injection then starting around here might help?:
http://msdn.microsoft.com/en-us/library ... 85%29.aspx

Also note that it might be better to use some of the more advanced debug OS API's
so you actually take a look at the allocation table of pages.
No point scanning $60000000-$70000000 if not a single page is allocated by the process in that range.
(freezing he process during this may be best so memory won't pop up or vanish while scanning, not all games like this though and you may have to run the trainer as admin too)

So I don't now. check msdn or search google for: process page allocation
or variants of words like that maybe?
BTW! Why not peak at how CheatEngine does it, the source is available I think, unlike with ArtMoney.

Re: Get the memory range and size available to your process!

Posted: Thu Sep 02, 2010 11:51 pm
by Thorium
That are 8TB not GB.
And it doesnt matters how much memory you have installed, size of virtual address space is fix.

Re: Get the memory range and size available to your process!

Posted: Thu Sep 02, 2010 11:54 pm
by Thorium
For trainers you can enumerate the allocated memory regions by using VirtualQueryEx. Search on MSDN for it.

Re: Get the memory range and size available to your process!

Posted: Thu Sep 02, 2010 11:57 pm
by Rescator
Thorium wrote:That are 8TB not GB.
And it doesnt matters how much memory you have installed, size of virtual address space is fix.
Oops, your right, thanks, corrected my statement! :)
Thorium wrote:For trainers you can enumerate the allocated memory regions by using VirtualQueryEx. Search on MSDN for it..
Ah VirtualQueryEx. Well PB, Thorium pointed you in the right direction, now go go go little codemonekey ;P

Although I don't envy you crawling through Windows memory API's heh...

Re: Get the memory range and size available to your process!

Posted: Fri Sep 03, 2010 3:48 am
by Thorium
Rescator wrote: Ah VirtualQueryEx. Well PB, Thorium pointed you in the right direction, now go go go little codemonekey ;P
Actualy i can provide a example. :D

It's from one of my old projects. I needed to get all allocated memory regions that contain executable code. That was because i wanted to hook the ingame console of a game without updating my program for every new version of the game. So i wrote some code that searches for the code to hook and hook it. It actualy worked very good. First written for a early beta and it's still working with the newest version.

However her is the procedure that enumerated all allocated memory regions that contain executable code.

It was written in PureBasic 4.20.

Code: Select all

Procedure.l GetExecutableMemRegions(RegionList.Region(1))

  Define.l Addr,RetVal,RegionCnt
  Define.MEMORY_BASIC_INFORMATION MemoryInfo

  RegionCnt = -1

  Repeat
  
    Addr = Addr + MemoryInfo\RegionSize
    RetVal = VirtualQuery_(Addr,MemoryInfo,SizeOf(MEMORY_BASIC_INFORMATION))
    
    If RetVal > 0 
      If MemoryInfo\State = #MEM_COMMIT
      
        If MemoryInfo\Protect = #PAGE_EXECUTE Or MemoryInfo\Protect = #PAGE_EXECUTE_READ Or MemoryInfo\Protect = #PAGE_EXECUTE_READWRITE Or MemoryInfo\Protect = #PAGE_EXECUTE_WRITECOPY
        
          RegionCnt = RegionCnt + 1
          ReDim RegionList.Region(RegionCnt)
          RegionList(RegionCnt)\BaseAddr = MemoryInfo\BaseAddress
          RegionList(RegionCnt)\Size = MemoryInfo\RegionSize
          
        EndIf
      
      EndIf  
    EndIf
  
  Until RetVal < 1

  ProcedureReturn RegionCnt

EndProcedure
To make it operate on another process change VirtualQuery_ to VirtualQueryEx_ and add the process handle parameter.

Re: Get the memory range and size available to your process!

Posted: Fri Sep 03, 2010 11:59 am
by Kwai chang caine
Thanks you very much MASTER RESCATOR ...you are an angel
Image

Thanks to MASTER THORIUM for your code too, but i have an error "Not found structure region" :(

Re: Get the memory range and size available to your process!

Posted: Fri Sep 03, 2010 7:40 pm
by Crusiatus Black

Code: Select all

Structure Region
  *BaseAddr
  Size.i
EndStructure
The code missed the structure :)