代码拉取完成,页面将自动刷新
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.
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。