Ai
1 Star 0 Fork 0

phy0292/cheat-engine

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
ValueFinder.pas 6.94 KB
一键复制 编辑 原始数据 按行查看 历史
cheat-engine 提交于 2019-12-20 00:49 +08:00 . Fix registry issues
unit ValueFinder;
{$MODE Delphi}
{
Designed fro use with the pointerscan.
With some fiddling it might be used for some other stuff as well
}
interface
{$ifdef windows}
uses windows, LCLIntf, classes, sysutils, symbolhandler, math, cefuncproc,newkernelhandler, commonTypeDefs;
{$endif}
{$ifdef darwin}
uses macport, LCLIntf, classes, sysutils, symbolhandler, math, cefuncproc,newkernelhandler, commonTypeDefs;
{$endif}
type TValueFinder=class
private
buffer: pointer;
memregionofBuffer: integer;
memregions: TMemoryRegions;
stopaddress: ptrUint;
function ismatchtovalue(p: pointer): boolean;
procedure quicksortmemoryregions(lo,hi: integer);
public
valuetype: TVariableType;
valuescandword: dword;
valuescansingle: single;
valuescandouble: double;
valuescansinglemax: single;
valuescandoublemax: double;
alligned: boolean;
function FindValue(startaddress: ptrUint): ptrUint;
constructor create(startaddress, stopaddress: ptrUint);
destructor destroy; override;
end;
implementation
uses ProcessHandlerUnit, Globals;
procedure TValueFinder.quicksortmemoryregions(lo,hi: integer);
var i,j: integer;
x,h: TMemoryRegion;
begin
i:=lo;
j:=hi;
x:=memregions[(lo+hi) div 2];
repeat
while (memregions[i].BaseAddress<x.BaseAddress) do inc(i);
while (memregions[j].BaseAddress>x.BaseAddress) do dec(j);
if i<=j then
begin
h:=memregions[i];
memregions[i]:=memregions[j];
memregions[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;
function TValueFinder.ismatchtovalue(p: pointer): boolean;
begin
result:=false;
case valuetype of
vtDword: result:=pdword(p)^=valuescandword;
vtSingle: result:=(psingle(p)^>=valuescansingle) and (psingle(p)^<valuescansinglemax);
vtDouble: result:=(pdouble(p)^>=valuescandouble) and (pdouble(p)^<valuescandoublemax);
end;
end;
function TValueFinder.FindValue(startaddress: ptrUint): ptrUint;
{
Pre: Called from lowest to highest value. NO RANDOM
}
var currentaddress: ptrUint;
i: integer;
valuesize: integer;
x: ptruint;
offset: dword;
begin
if valuetype=vtdouble then valuesize:=8 else valuesize:=4;
result:=0;
if memregionofbuffer = -1 then exit; //failure loading ANY region at create time
currentaddress:=startaddress;
while currentaddress<stopaddress do
begin
if currentaddress<memregions[memregionofbuffer].baseaddress then
currentaddress:=memregions[memregionofbuffer].baseaddress;
if (currentaddress>(memregions[memregionofbuffer].baseaddress+memregions[memregionofbuffer].memorysize)) then
begin
if memregionofbuffer+1>=length(memregions) then exit; //nothing else found
i:=memregionofbuffer+1;
while (i<length(memregions)) do
begin
if readprocessmemory(processhandle, pointer(memregions[i].baseaddress), buffer, memregions[i].MemorySize,x) then
begin
memregionofbuffer:=i;
currentaddress:=memregions[memregionofbuffer].baseaddress;
break;
end
else
inc(i);
end;
if i>=length(memregions) then exit; //no readable memory found
end;
//still here so the current address falls in the currently loaded buffer
offset:=currentaddress-memregions[memregionofbuffer].baseaddress;
if offset+valuesize<memregions[memregionofbuffer].memorysize then
begin
//it falls withing the region
if ismatchtovalue(@pbytearray(buffer)[offset]) then
begin
//found one
result:=currentaddress;
exit;
end;
end;
if alligned then
inc(currentaddress,processhandler.pointersize)
else
inc(currentaddress);
end;
end;
constructor TValueFinder.create(startaddress, stopaddress: ptrUint);
var address: ptrUint;
i: integer;
maxsize: dword;
mbi: MEMORY_BASIC_INFORMATION;
x: ptruint;
begin
memregionofbuffer:=-1;
self.stopaddress:=stopaddress;
//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(memregions,length(memregions)+1);
memregions[length(memregions)-1].BaseAddress:=ptrUint(mbi.baseaddress); //just remember this location
memregions[length(memregions)-1].MemorySize:=mbi.RegionSize;
end;
address:=ptrUint(mbi.baseaddress)+mbi.RegionSize;
end;
//split up the memory regions into small chunks of max 512KB (so don't allocate a fucking 1GB region)
i:=0;
while i<length(memregions) do
begin
if memregions[i].MemorySize>512*1024 then
begin
//too big, so cut into pieces
//create new entry with 512KB less
setlength(memregions,length(memregions)+1);
memregions[length(memregions)-1].BaseAddress:=memregions[i].BaseAddress+512*1024;
memregions[length(memregions)-1].MemorySize:=memregions[i].MemorySize-512*1024;
memregions[i].MemorySize:=512*1024; //set the current region to be 512KB
end;
inc(i); //next item. Eventually the new items will be handled, and they will also be split untill the list is finally cut into small enough chunks
end;
//sort memoryregions from small to high
quicksortmemoryregions(0,length(memregions)-1);
//let's load the first region (assuming the user wants to start from the beginning)
maxsize:=0;
for i:=0 to length(memregions)-1 do
maxsize:=max(maxsize,memregions[i].MemorySize);
getmem(buffer,maxsize);
i:=0;
while (i<length(memregions)) and (memregionofbuffer=-1) do
begin
if readprocessmemory(processhandle, pointer(memregions[i].baseaddress), buffer, memregions[i].MemorySize,x) then
memregionofbuffer:=i
else
inc(i);
end;
end;
destructor TValueFinder.destroy;
begin
if buffer<>nil then
freememandnil(buffer);
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

搜索帮助