Ai
1 Star 0 Fork 0

phy0292/cheat-engine

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
RemoteMemoryManager.pas 6.29 KB
一键复制 编辑 原始数据 按行查看 历史
cheat-engine 提交于 2019-12-20 00:49 +08:00 . Fix registry issues
unit RemoteMemoryManager;
{
this unit will contain a class that will be used to control remotely allocated memory blocks.
Specifically designed for smaller allocations. allocate at least systeminfo.dwAllocationGranularity on each real alloc (64kb)
Speed is not of essence here. Assumed it that only up to 8KB of memory will be used at MOST
}
{$mode delphi}
interface
uses
{$ifdef darwin}
macport,
{$endif}
{$ifdef windows}
windows,
{$endif}
syncobjs, Classes, SysUtils, cefuncproc, newkernelhandler;
type
TAllocs=record //record describing each little allocated block of memory
address: ptruint;
size: dword;
end;
PAllocs=^TAllocs;
type
TAllocatedRegion=record
remotebase: ptruint; //size is not stored, that is systeminfo.dwAllocationGranularity
allocs: Tlist; //sorted list of allocations
end;
PAllocatedRegion=^TAllocatedRegion;
type
TRemoteMemoryManager=class(tobject)
private
cs: TCriticalsection;
allocatedRegions: Tlist;
bigAllocs: Tlist;
function findFreeRegion(size: dword): ptruint;
procedure addNewAlloc(address: ptruint; size: integer);
public
function alloc(size: dword):ptruint;
procedure dealloc(address: ptruint);
constructor create;
destructor destroy; override;
end;
implementation
uses ProcessHandlerUnit;
procedure TRemoteMemoryManager.addNewAlloc(address: ptruint; size: integer);
var i,j: integer;
a,b: PAllocs;
ar: PAllocatedRegion;
begin
getmem(a, sizeof(TAllocs));
a.address:=address;
a.size:=size;
for i:=0 to allocatedRegions.count-1 do
begin
ar:=PAllocatedRegion(allocatedRegions[i]);
if InRangeQ(address, ar.remotebase, ar.remotebase+systeminfo.dwAllocationGranularity) then
begin
for j:=0 to ar.allocs.Count-1 do
begin
b:=PAllocs(ar.allocs[j]);
if b.address>address then //insert the address before this one
begin
ar.allocs.Insert(j,a);
exit; //inserted the alloc data. leave now
end;
end;
//still here, add it to the end
ar.allocs.Add(a);
break;
end;
end;
end;
function TRemoteMemoryManager.findFreeRegion(size: dword): ptruint;
var i,j: integer;
currentTry: ptruint;
a: PAllocs;
ar: PAllocatedRegion;
begin
result:=0;
//scan the regions for a gap of at least size bytes
for i:=0 to allocatedRegions.count-1 do
begin
ar:=PAllocatedRegion(allocatedRegions[i]);
currentTry:=ar.remotebase;
for j:=0 to ar.allocs.count-1 do
begin
a:=PAllocs(ar.allocs[j]); //keep in mind: sorted list
if ((currentTry+size)>=a.address) then //too big to be used here
currentTry:=qword(a.address)+a.size //not usable, try the next block
else //this block seems usable
break; //this block seems usable
end;
//check if we're not outside of the allocated region
if (currentTry+size)<(ar.remotebase+ systeminfo.dwAllocationGranularity) then //found a usable block that falls within a allocated region
begin
result:=currentTry;
break;
end;
end;
end;
function TRemoteMemoryManager.alloc(size: dword):ptruint;
var i: integer;
ar: PAllocatedRegion;
begin
result:=0;
if size=0 then exit;
//make it so size is always at least dividable by 4 (means min size is 4)
i:=size mod 4;
if i>0 then
size:=size + (4-i);
if size>=systeminfo.dwAllocationGranularity then //can't be handled with the small handler
begin
result:=ptruint(VirtualAllocEx(processhandle,nil,size,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE));
if result<>0 then
begin
cs.enter;
bigAllocs.Add(pointer(result));
cs.leave;
end;
end
else
begin
//small enough
cs.enter;
try
result:=findFreeRegion(size);
if result=0 then
begin
//no free region found
result:=ptruint(VirtualAllocEx(processhandle,nil,systeminfo.dwAllocationGranularity,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE));
if result<>0 then
begin
ar:=getmem(sizeof(TAllocatedRegion));
ar.remotebase:=result;
ar.allocs:=tlist.create;
allocatedRegions.Add(ar);
end;
end;
addNewAlloc(result, size);
finally
cs.leave;
end;
end;
end;
procedure TRemoteMemoryManager.dealloc(address: ptruint);
var i,j: integer;
ar: PAllocatedRegion;
b: PAllocs;
begin
cs.enter;
try
for i:=0 to allocatedRegions.count-1 do
begin
ar:=PAllocatedRegion(allocatedRegions[i]);
if InRangeQ(address, ar.remotebase, ar.remotebase+systeminfo.dwAllocationGranularity) then
begin
for j:=0 to ar.allocs.Count-1 do
begin
b:=PAllocs(ar.allocs[j]);
if address=b.address then //insert the address before this one
begin
//found it
FreeMemAndNil(b);
ar.allocs.Delete(j);
if ar.allocs.Count=0 then //completely freed this region
begin
virtualfreeex(processhandle,pointer(ar.remotebase),0,MEM_RELEASE);
freeandnil(ar.allocs);
FreeMemAndNil(ar);
allocatedRegions.Delete(i);
end;
exit;
end;
end;
end;
end;
//not found, check the big alloc region
i:=bigallocs.IndexOf(pointer(address));
if i<>-1 then
begin
virtualfreeex(processhandle,pointer(address),0,MEM_RELEASE);
bigallocs.Delete(i);
end;
finally
cs.leave;
end;
end;
constructor TRemoteMemoryManager.create;
begin
cs:=TCriticalsection.create;
allocatedRegions:=tlist.create;
bigallocs:=Tlist.create;
end;
destructor TRemoteMemoryManager.destroy;
var i,j: integer;
begin
//don't dealloc the memory, but do free the structures allocated here
for i:=0 to allocatedRegions.count-1 do
begin
for j:=0 to PAllocatedRegion(allocatedRegions[i]).allocs.Count-1 do
FreeMem(PAllocatedRegion(allocatedRegions[i]).allocs[j]);
PAllocatedRegion(allocatedRegions[i]).allocs.Free;
FreeMem(allocatedRegions[i]);
end;
freeandnil(allocatedRegions);
freeandnil(bigallocs);
freeandnil(cs);
end;
end.
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/phy0292/cheat-engine.git
git@gitee.com:phy0292/cheat-engine.git
phy0292
cheat-engine
cheat-engine
master

搜索帮助