1 Star 0 Fork 0

phy0292/cheat-engine

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
rescanhelper.pas 6.65 KB
一键复制 编辑 原始数据 按行查看 历史
cheat-engine 提交于 2019-12-20 00:49 +08:00 . Fix registry issues
unit rescanhelper;
{$MODE Delphi}
interface
{$ifdef darwin}
uses macport, LCLIntf, classes, symbolhandler, CEFuncProc,NewKernelHandler, maps,
sysutils, syncobjs, pagemap, Sockets, (*CELazySocket, PointerscanNetworkCommands, *)
zstream, commonTypeDefs;
{$endif}
{$ifdef windows}
uses windows, LCLIntf, classes, symbolhandler, CEFuncProc,NewKernelHandler, maps,
sysutils, syncobjs, pagemap, Sockets, CELazySocket, PointerscanNetworkCommands,
zstream, commonTypeDefs;
{$endif}
type
TRescanHelper=class
private
pagemap: TPageMap;
pagemapcs: TCriticalsection;
memoryregion: TMemoryRegions;
function BinSearchMemRegions(address: ptrUint): integer;
procedure quicksortmemoryregions(lo,hi: integer);
public
function ispointer(address: ptrUint): boolean;
function GetMemoryRegion(Address: ptruint): TMemoryRegion;
function FindPage(index: ptruint): TPageInfo;
function getMemoryRegions: TMemoryRegions;
constructor create;
destructor destroy; override;
end;
implementation
uses ProcessHandlerUnit, Globals;
function TRescanHelper.BinSearchMemRegions(address: ptrUint): integer;
var
First: Integer;
Last: Integer;
Found: Boolean;
Pivot: integer;
begin
First := 0; //Sets the first item of the range
Last := length(memoryregion)-1; //Sets the last item of the range
Found := False; //Initializes the Found flag (Not found yet)
Result := -1; //Initializes the Result
while (First <= Last) and (not Found) do
begin
//Gets the middle of the selected range
Pivot := (First + Last) div 2;
//Compares the String in the middle with the searched one
if (address >= memoryregion[Pivot].BaseAddress) and (address<memoryregion[Pivot].BaseAddress+memoryregion[Pivot].MemorySize) then
begin
Found := True;
Result := Pivot;
end
//If the Item in the middle has a bigger value than
//the searched item, then select the first half
else if memoryregion[Pivot].BaseAddress > address then
Last := Pivot - 1
//else select the second half
else
First := Pivot + 1;
end;
end;
function TRescanHelper.ispointer(address: ptrUint): boolean;
{
Check the memoryregion array for this address. If it's in, return true
}
begin
result:=BinSearchMemRegions(address)<>-1;
end;
function TRescanHelper.GetMemoryRegion(Address: ptruint): TMemoryRegion;
var i: integer;
begin
i:=BinSearchMemRegions(address);
if i<>-1 then
result:=memoryregion[BinSearchMemRegions(address)]
else
result.BaseAddress:=0;
end;
function TRescanHelper.findPage(Index: ptrUint): TPageInfo;
{
will find the pageinfo. If not found, it will add it
}
var
pi: TPageInfo;
x: ptruint;
r: PPageInfo;
begin
//the old method is faster, but has a small threading issue where adding new entries would lead to a memory leak if multiple threads added the same thing
r:=pagemap.GetPageInfo(index);
if r=nil then
begin
//not yet added, add it to the list
pi.data:=nil;
if ispointer(index shl 12) then
begin
//save the data
{if socket>=0 then
begin
result:=DownloadPages(index shl 12);
exit;
end
else }
begin
getmem(pi.data, 4096);
if ReadProcessMemory(ProcessHandle, pointer(index shl 12), pi.data, 4096, x)=false then
begin
//unexpected failure reading the memory
freememandnil(pi.data);
end;
end;
end;
pagemapcs.enter; //adding on the other hand does require a lock, as it needs to fidn out where to add it, and what variables to initialize to what value (next/previous)
r:=pagemap.GetPageInfo(index);
if r=nil then
begin
//not yet added by another thread
//add it
pagemap.Add(index, pi.data);
result:=pi;
end
else
begin
//another thread added it, abort
if pi.data<>nil then
freememandnil(pi.data);
result:=r^;
end;
pagemapcs.Leave;
end
else //found:
result:=r^;
end;
function TRescanHelper.getMemoryRegions: TMemoryRegions;
begin
result:=memoryregion;
end;
procedure TRescanHelper.quicksortmemoryregions(lo,hi: integer);
var i,j: integer;
x,h: TMemoryRegion;
begin
i:=lo;
j:=hi;
if hi<0 then exit;
x:=memoryregion[(lo+hi) div 2];
repeat
while (memoryregion[i].BaseAddress<x.BaseAddress) do inc(i);
while (memoryregion[j].BaseAddress>x.BaseAddress) do dec(j);
if i<=j then
begin
h:=memoryregion[i];
memoryregion[i]:=memoryregion[j];
memoryregion[j]:=h;
inc(i);
dec(j);
end;
until i>j;
if (lo<j) then quicksortmemoryregions(lo,j);
if (i<hi) then quicksortmemoryregions(i,hi);
end;
constructor TRescanHelper.create;
var
mbi : _MEMORY_BASIC_INFORMATION;
address: ptrUint;
i: integer;
begin
pagemap:=TPageMap.Create;
pagemapcs:=TCriticalSection.create;
//enumerate all memory regions
address:=0;
while (Virtualqueryex(processhandle,pointer(address),mbi,sizeof(mbi))<>0) and ((address+mbi.RegionSize)>address) do
begin
if (not symhandler.inSystemModule(ptrUint(mbi.baseAddress))) and (not (not scan_mem_private and (mbi._type=mem_private))) and (not (not scan_mem_image and (mbi._type=mem_image))) and (not (not scan_mem_mapped and ((mbi._type and mem_mapped)>0))) and (mbi.State=mem_commit) and ((mbi.Protect and page_guard)=0) and ((mbi.protect and page_noaccess)=0) then //look if it is commited
begin
if Skip_PAGE_NOCACHE then
if (mbi.AllocationProtect and PAGE_NOCACHE)=PAGE_NOCACHE then
begin
address:=ptrUint(mbi.BaseAddress)+mbi.RegionSize;
continue;
end;
{$ifdef windows}
if Skip_PAGE_WRITECOMBINE then
if (mbi.AllocationProtect and PAGE_WRITECOMBINE)=PAGE_WRITECOMBINE then
begin
address:=ptrUint(mbi.BaseAddress)+mbi.RegionSize;
continue;
end;
{$endif}
setlength(memoryregion,length(memoryregion)+1);
memoryregion[length(memoryregion)-1].BaseAddress:=ptrUint(mbi.baseaddress); //just remember this location
memoryregion[length(memoryregion)-1].MemorySize:=mbi.RegionSize;
end;
address:=ptrUint(mbi.baseaddress)+mbi.RegionSize;
end;
//sort memoryregions from small to high
quicksortmemoryregions(0,length(memoryregion)-1);
end;
destructor TRescanHelper.destroy;
var i: integer;
data: PByteArray;
begin
setlength(memoryregion,0);
pagemapcs.free;
pagemap.Free;
inherited destroy;
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

搜索帮助