📄 foundlisthelper.pas.svn-base
字号:
unit foundlisthelper;
interface
uses windows,sysutils,classes,ComCtrls,StdCtrls,symbolhandler, cefuncproc,
newkernelhandler, memscan;
type TScanType=(fs_advanced,fs_addresslist);
type
TFoundList=class;
TRebaseAgain=class(tthread)
private
procedure rerebase;
public
foundlist: TFoundList;
procedure execute; override;
end;
TFoundList=class
private
foundlist: TListView;
foundcountlabel: tlabel;
addressfile: tfilestream;
scantype: TScanType;
fvartype: integer;
varlength: integer; //bitlength, stringlength
hexadecimal: boolean; //show result in hexadecimal notation (when possible)
signed: boolean;
unicode: boolean;
binaryasdecimal: boolean;
lastrebase: integer;
addresslist: array [0..1023] of dword; //this is a small list of addresses in the list
addresslistb: array [0..1023] of TBitAddress; //idem, but in case of bit
addresslistfirst: dword; //index number the addresslist[0] has
valuelist: array [0..1023] of string;
RebaseAgainThread: TRebaseAgain;
public
function GetVarLength: integer;
procedure DeleteResults;
procedure deleteaddress(i:integer);
procedure clear;
procedure RefetchValueList;
function Initialize(vartype: integer):int64; overload;
function Initialize(vartype,varlength: integer; hexadecimal,signed,binaryasdecimal,unicode: boolean):int64; overload; //initialize after a scan
procedure Deinitialize; //free filehandles before the scan
function GetStartBit(i: integer):dword;
function GetAddressOnly(i: integer; var extra: dword): dword;
function GetAddress(i: integer;var extra: dword; var value:string): dword; overload; //extra for stuff like bitnr
function GetAddress(i: integer):dword; overload;
function InModule(i: integer):boolean;
function GetModuleNamePlusOffset(i: integer):string;
procedure RebaseAddresslist(i: integer);
procedure RebaseAddresslistAgain; //calls rebaseaddresslist with the same parameter as last time
property vartype: integer read fvartype;
constructor create(foundlist: tlistview; foundcountlabel: tlabel);
end;
implementation
procedure TRebaseAgain.rerebase;
begin
foundlist.RebaseAgainThread:=nil; //so it will spawn a new one if still not done
foundlist.RebaseAddresslistAgain;
foundlist.foundlist.Refresh;
end;
procedure TRebaseAgain.execute;
begin
freeonterminate:=true;
sleep(1000);
synchronize(rerebase);
end;
procedure TFoundList.clear;
begin
foundlist.Items.Count:=0;
addresslistfirst:=0;
foundlist.Clear;
end;
function TFoundList.InModule(i: integer):boolean;
var mi: tmoduleinfo;
begin
result:=symhandler.getmodulebyaddress(getaddress(i),mi);
end;
function TFoundList.GetModuleNamePlusOffset(i: integer):string;
var mi: tmoduleinfo;
x: dword;
begin
x:=getaddress(i);
if symhandler.getmodulebyaddress(x,mi) then
result:=mi.modulename+'+'+inttohex(x-mi.baseaddress,1)
else
result:=inttohex(x,8);
end;
function TFoundList.GetVarLength:integer;
begin
result:=varlength;
end;
procedure TFoundList.deleteaddress(i:integer);
var memoryfile: tfilestream;
outaddress: tfilestream;
outmemory: tfilestream;
addresspos: int64;
memorypos: int64;
j,k: integer;
buf: pointer;
begin
if addressfile=nil then exit;
try
memoryfile:=tfilestream.Create(CheatEngineDir+'Memory.TMP',fmOpenRead or fmShareDenyNone);
outaddress:=tfilestream.Create(CheatEngineDir+'Addresses.NEW',fmCreate or fmShareDenyNone);
outmemory:=tfilestream.Create(CheatEngineDir+'Memory.NEW',fmCreate or fmShareDenyNone);
except
exit;
end;
getmem(buf,512*1024);
try
//memoryfile is initialized
if vartype in [5,9] then
addresspos:=7+sizeof(sizeof(TBitAddress))*i
else
addresspos:=7+sizeof(sizeof(dword))*i;
case vartype of
0: memorypos:=sizeof(byte)*i;
1: memorypos:=sizeof(word)*i;
2: memorypos:=sizeof(dword)*i;
3: memorypos:=sizeof(single)*i;
4: memorypos:=sizeof(double)*i;
6: memorypos:=sizeof(int64)*i;
end; //no 5 and 7 since they have no values
addressfile.Position:=0;
memoryfile.Position:=0;
outaddress.CopyFrom(addressfile,addresspos);
if vartype in [5,9] then
addressfile.Position:=addresspos+sizeof(TBitAddress)
else
addressfile.Position:=addresspos+sizeof(dword);
if addressfile.Size-addressfile.Position>0 then
outaddress.CopyFrom(addressfile,addressfile.Size-addressfile.Position);
//memory
if not (vartype in [5,7]) then
begin
outmemory.CopyFrom(memoryfile,memorypos);
memoryfile.Position:=memorypos+sizeof(dword);
if memoryfile.Size-memoryfile.Position>0 then
outmemory.CopyFrom(memoryfile,memoryfile.Size-memoryfile.Position);
end;
finally
memoryfile.free;
outaddress.free;
outmemory.free;
freemem(buf);
end;
//still here, not crashed, so out with the old, in with the new...
deinitialize;
deletefile(CheatEngineDir+'Memory.TMP');
deletefile(CheatEnginedir+'Addresses.TMP');
renamefile(CheatEngineDir+'Memory.NEW',CheatEngineDir+'Memory.TMP');
renamefile(CheatEngineDir+'Addresses.NEW',CheatEngineDir+'Addresses.TMP');
Initialize(vartype);
end;
procedure TFoundList.RebaseAddresslistAgain;
begin
RebaseAddresslist(lastrebase);
end;
procedure TFoundList.RebaseAddresslist(i: integer);
var j,k: dword;
begin
if addressfile=nil then exit; //during a scan
lastrebase:=i;
//reload buffer from index i-512; //so 512 above and below (result has to be bigger than or equal to 0)
if i>512 then
j:=i-512
else
j:=0;
//fill addresslist
k:=foundlist.Items.Count-j;
if k>1024 then k:=1024;
if vartype in [5,9] then
begin
addressfile.Position:=7+j*sizeof(TBitAddress);
k:=sizeof(TBitAddress)*k;
addressfile.ReadBuffer(addresslistb[0],k);
addresslistfirst:=j;
end
else
begin
addressfile.Position:=7+j*sizeof(dword);
k:=sizeof(dword)*k;
addressfile.ReadBuffer(addresslist[0],k);
if (k>8) and (addresslist[0]=addresslist[1]) then
begin
//create a thread that calls rebase after a second
if RebaseAgainThread=nil then
begin
RebaseAgainThread:=TRebaseAgain.Create(true);
RebaseAgainThread.foundlist:=self;
RebaseAgainThread.Resume;
end;
end;
addresslistfirst:=j;
end;
for i:=0 to 1023 do
if valuelist[i]<>'' then
valuelist[i]:='';
end;
procedure TFoundList.RefetchValueList;
var i,j: integer;
oldvalues: array of string;
si,l: integer;
x: dword;
temp: string;
begin
if addressfile=nil then exit;
si:=foundlist.TopItem.index;
if si>=0 then
begin
l:=foundlist.VisibleRowCount;
setlength(oldvalues,l);
j:=0;
for i:=si to si+l-1 do
begin
GetAddress(i,x,oldvalues[j]);
inc(j);
end;
end;
for i:=0 to 1023 do
if valuelist[i]<>'' then
valuelist[i]:='';
if si>=0 then
begin
//update the changed ones
j:=0;
for i:=si to si+l-1 do
begin
getaddress(i,x,temp);
if temp<>oldvalues[j] then foundlist.Items[i].Update;
inc(j);
end;
end;
end;
function TFoundList.GetStartBit(i: integer):dword;
var extra: dword;
begin
GetAddressOnly(i,extra);
result:=extra;
end;
function TFoundList.GetAddressOnly(i: integer; var extra: dword): dword;
var j: integer;
begin
if i=-1 then exit;
extra:=0;
result:=0;
if addressfile=nil then exit; //during a scan
if scantype=fs_advanced then exit; //should never happen...
if (i<addresslistfirst) or (i>=addresslistfirst+1024) then
RebaseAddresslist(i);
j:=i-addresslistfirst;
if vartype in [5,9] then //bit,all
begin
result:=addresslistb[j].address;
extra:=addresslistb[j].bit;
end
else
begin
result:=addresslist[j];
end;
if result=0 then //address 0 is usually not possible
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -