📄 structuresfrm.pas
字号:
returns: -1,-4,-7,-12,-13,-14
}
var x: string;
i: integer;
isstring: boolean;
begin
result:=0;
i:=address mod 4;
case i of
1: //1 byte
begin
result:=-1;
exit;
end;
2,3: //2 byte
begin
result:=-4;
exit;
end;
end;
if size>=8 then //check if a double can be used
begin
if pdouble(@buf[0])^<>0 then
begin
x:=floattostr(pdouble(@buf[0])^);
if (pos('E',x)=0) then //no exponent
begin
//check if the value isn't bigger or smaller than 1000000 or smaller than -1000000
if (pdouble(@buf[0])^<1000000) and (pdouble(@buf[0])^>-1000000) then
begin
result:=-13;
exit;
end;
end;
end;
end;
if (size>=2) and (size<4) then
begin
result:=-4;
exit;
end;
if (size=1) then
begin
result:=-1;
exit;
end;
//still here so either 4, or not a double
//check if it confirms to a single float
if psingle(@buf[0])^<>0 then
begin
x:=floattostr(psingle(@buf[0])^);
if (pos('E',x)=0) then //no exponent
begin
//check if the value isn't bigger or smaller than 1000000 or smaller than -1000000
if (psingle(@buf[0])^<1000000) and (psingle(@buf[0])^>-1000000) then
begin
result:=-12;
exit;
end;
end;
end;
//still here, so check if it matches a string
isstring:=true;
i:=0;
while i<4 do
begin
//check if the first 4 characters match with a standard ascii values (32 to 127)
if (buf[i]<32) or (buf[i]>127) then
begin
isstring:=false;
break;
end;
inc(i);
end;
if isstring then
begin
result:=-14;
exit;
end;
//none of the above, so....
result:=-7;
end;
procedure TfrmStructures.Definenewstructure1Click(Sender: TObject);
var sstructsize:string;
autofillin,structsize: integer;
structname: string;
buf: array of byte;
buf2: array of byte;
i,j,t: integer;
x,y: dword;
begin
if not inputquery('Structure define','Give the name for this structure',structname) then exit;
autofillin:=messagedlg('Do you want Cheat Engine to try and fill in the most basic types of the struct using the current address?',mtconfirmation,[mbyes,mbno,mbcancel],0);
if autofillin=mrcancel then exit;
setlength(definedstructures,length(definedstructures)+1);
definedstructures[length(definedstructures)-1].name:=structname;
refreshmenuitems;
structures1.Items[structures1.Count-1].Click;
if autofillin=mryes then
begin
sstructsize:='512';
if not inputquery('Structure define','Please give a starting size of the struct (You can change this later if needed)',Sstructsize) then exit;
structsize:=strtoint(sstructsize);
setlength(buf,structsize);
setlength(buf2,8);
//now read the memory
if readprocessmemory(processhandle,pointer(address),@buf[0],structsize,x) then
begin
x:=0;
while x<structsize do
begin
i:=length(definedstructures[length(definedstructures)-1].structelement);
setlength(definedstructures[length(definedstructures)-1].structelement,i+1);
definedstructures[length(definedstructures)-1].structelement[i].pointerto:=false;
if isreadable(pdword(@buf[x])^) and (pdword(@buf[x])^ mod 4=0) then
begin
//pointer
definedstructures[length(definedstructures)-1].structelement[i].pointerto:=true;
definedstructures[length(definedstructures)-1].structelement[i].pointertoSize:=8;
definedstructures[length(definedstructures)-1].structelement[i].bytesize:=4;
definedstructures[length(definedstructures)-1].structelement[i].description:='pointer to ';
if readprocessmemory(processhandle,pointer(pdword(@buf[x])^),@buf2[0],8,y) then
begin
t:=RawToType(pdword(@buf[x])^,buf2[0],8);
definedstructures[length(definedstructures)-1].structelement[i].structurenr:=t;
end
else definedstructures[length(definedstructures)-1].structelement[i].structurenr:=-9;
inc(x,4);
end
else
begin
//value
//check what type it is
t:=RawToType(address+x,buf[x],structsize-x);
definedstructures[length(definedstructures)-1].structelement[i].structurenr:=t;
case t of
-1: //byte
begin
definedstructures[length(definedstructures)-1].structelement[i].description:='Byte';
definedstructures[length(definedstructures)-1].structelement[i].bytesize:=1;
inc(x,1);
end;
-4: //word
begin
definedstructures[length(definedstructures)-1].structelement[i].description:='Word';
definedstructures[length(definedstructures)-1].structelement[i].bytesize:=2;
inc(x,2);
end;
-7: //dword
begin
definedstructures[length(definedstructures)-1].structelement[i].description:='Dword';
definedstructures[length(definedstructures)-1].structelement[i].bytesize:=4;
inc(x,4);
end;
-12: //single
begin
definedstructures[length(definedstructures)-1].structelement[i].description:='Float';
definedstructures[length(definedstructures)-1].structelement[i].bytesize:=4;
inc(x,4);
end;
-13: //double
begin
definedstructures[length(definedstructures)-1].structelement[i].description:='Double';
definedstructures[length(definedstructures)-1].structelement[i].bytesize:=8;
inc(x,8);
end;
-14: //string
begin
definedstructures[length(definedstructures)-1].structelement[i].description:='String';
//find out how long this string is:
definedstructures[length(definedstructures)-1].structelement[i].bytesize:=0;
while (x<structsize) and (buf[x]>=32) and (buf[x]<=127) do
begin
inc(x);
inc(definedstructures[length(definedstructures)-1].structelement[i].bytesize);
end;
end;
end;
end;
end;
end;
end;
refreshmenuitems;
currentstructure.refresh;
end;
procedure TfrmStructures.definedstructureselect(sender:tobject);
begin
caption:='Memory dissect - '+(sender as tmenuitem).Caption;
if currentstructure<>nil then
freeandnil(currentstructure);
treeview1.Items.Clear;
currentstructure:=tstructure.create(treeview1,treeview1.Items.Add(nil,edtaddress.text+'-'+definedstructures[(sender as tmenuitem).Tag].name),address,(sender as tmenuitem).Tag);
currentstructure.refresh;
refreshmenuitems;
end;
procedure TfrmStructures.refreshmenuitems;
var i: integer;
mi: tmenuitem;
begin
//go through the definedstructures array and see if they are int the list or not
//delete the ones that are too many
while (structures1.Count-2)>length(definedstructures) do
structures1.Delete(structures1.Count-1); //delete the last one
for i:=0 to length(definedstructures)-1 do
begin
if i<structures1.Count-2 then
begin
//check the name, and update if needed
if structures1.Items[i+2].Caption<>definedstructures[i].name then
structures1.Items[i+2].Caption:=definedstructures[i].name;
end
else //add it
begin
mi:=tmenuitem.Create(self);
mi.Caption:=definedstructures[i].name;
mi.OnClick:=definedstructureselect;
mi.Tag:=i;
structures1.Add(mi);
end;
if (currentstructure<>nil) and (currentstructure.basestructure=i) then
structures1.Items[i+2].Checked:=true
else
structures1.Items[i+2].Checked:=false;
end;
end;
procedure TfrmStructures.Addelement1Click(Sender: TObject);
var d,i,j,k,l:integer;
size: dword;
structtype: string;
selectedstructure: tstructure;
selectedelement: integer;
selectednode: ttreenode;
begin
selectednode:=treeview1.Selected;
if selectednode=nil then
selectedstructure:=currentstructure
else
selectedstructure:=tstructure(selectednode.Data);
if selectedstructure=nil then
selectedstructure:=currentstructure;
if selectedstructure.basestructure<0 then
begin
selectedstructure:=tstructure(selectednode.parent);
selectednode:=selectednode.Parent;
end;
if selectednode=nil then //lastnode
selectedelement:=length(definedstructures[selectedstructure.basestructure].structelement)-1
else
begin
selectedelement:=selectednode.index-1;
end;
if currentstructure=nil then raise exception.Create('First select a structure you want to modify or define one first');
with tfrmstructuresaddelement.create(self) do
begin
//fill the combobox with possible types
//the base types, and defined types
cbtype.Items.AddObject('Byte',pointer(1));
cbtype.Items.AddObject('Byte Signed',pointer(1));
cbtype.Items.AddObject('Byte Hexadecimal',pointer(1));
cbtype.Items.AddObject('2 Bytes',pointer(2));
cbtype.Items.AddObject('2 Bytes Signed',pointer(2));
cbtype.Items.AddObject('2 Bytes Hexadecimal',pointer(2));
cbtype.Items.AddObject('4 Bytes',pointer(4));
cbtype.Items.AddObject('4 Bytes Signed',pointer(4));
cbtype.Items.AddObject('4 Bytes Hexadecimal',pointer(4));
cbtype.Items.AddObject('8 Bytes',pointer(8));
cbtype.Items.AddObject('8 Bytes Hexadecimal',pointer(8));
cbtype.Items.AddObject('Float',pointer(4));
cbtype.Items.AddObject('Double',pointer(8));
cbtype.Items.AddObject('String',pointer(10));
cbtype.Items.AddObject('String Unicode',pointer(10));
cbtype.ItemIndex:=8;
cbType.OnChange(cbType);
cbtype.DropDownCount:=17;
//and add the other defined structures as well
for i:=0 to length(definedstructures)-1 do
begin
size:=0;
for j:=0 to length(definedstructures[i].structelement)-1 do
inc(size,definedstructures[i].structelement[j].bytesize);
cbtype.Items.AddObject(definedstructures[i].name,pointer(size));
end;
if showmodal=mrok then
begin
if cbtype.ItemIndex=-1 then exit;
//allocate a spot for the new element
i:=length(definedstructures[selectedstructure.basestructure].structelement);
setlength(definedstructures[selectedstructure.basestructure].structelement,i+1);
//move the elements after selectedelement
for j:=i-1 downto selectedelement+1 do
definedstructures[selectedstructure.basestructure].structelement[j+1]:=definedstructures[selectedstructure.basestructure].structelement[j];
i:=selectedelement+1;
definedstructures[selectedstructure.basestructure].structelement[i].pointerto:=cbpointerto.checked;
definedstructures[selectedstructure.basestructure].structelement[i].description:=edtDescription.text;
if definedstructures[selectedstructure.basestructure].structelement[i].pointerto then
begin
if cbtype.itemindex<=14 then
definedstructures[selectedstructure.basestructure].structelement[i].structurenr:=-(cbtype.ItemIndex+1)
else
definedstructures[selectedstructure.basestructure].structelement[i].structurenr:=cbtype.ItemIndex-15;
definedstructures[selectedstructure.basestructure].structelement[i].bytesize:=4;
definedstructures[selectedstructure.basestructure].structelement[i].pointertosize:=bytesize;
end
else
begin
if cbtype.ItemIndex<=14 then //basetype
begin
definedstructures[selectedstructure.basestructure].structelement[i].structurenr:=-(cbtype.ItemIndex+1);
definedstructures[selectedstructure.basestructure].structelement[i].bytesize:=bytesize;
end
else
begin
//not a pointer, but also no base type, so just append the selected structure
j:=cbtype.ItemIndex-15; //j now contains the structure number
d:=length(definedstructures[j].structelement);
setlength(definedstructures[selectedstructure.basestructure].structelement,length(definedstructures[currentstructure.basestructure].structelement)+d-1);
//move the other elements as well
for k:=length(definedstructures[selectedstructure.basestructure].structelement)-1 downto selectedelement+d+1 do
definedstructures[selectedstructure.basestructure].structelement[k]:=definedstructures[selectedstructure.basestructure].structelement[k-d+1];
for k:=0 to length(definedstructures[j].structelement)-1 do
begin
definedstructures[selectedstructure.basestructure].structelement[i]:=definedstructures[j].structelement[k];
definedstructures[selectedstructure.basestructure].structelement[i].description:=edtDescription.text+'_'+definedstructures[j].structelement[k].description;
inc(i);
end;
end;
end;
currentstructure.refresh;
if not treeview1.Items.GetFirstNode.Expanded then
treeview1.Items.GetFirstNode.Expand(false);
end;
end;
end;
procedure TfrmStructures.updatetimerTimer(Sender: TObject);
begin
if currentstructure<>nil then currentstructure.refresh;
end;
procedure TfrmStructures.TreeView1Collapsing(Sender: TObject;
Node: TTreeNode; var AllowCollapse: Boolean);
begin
allowcollapse:=not (node=treeview1.Items.GetFirstNode);
end;
procedure TfrmStructures.Button1Click(Sender: TObject);
begin
address:=address+1;
end;
procedure TfrmStructures.Button2Click(Sender: TObject);
begin
address:=address-1;
end;
procedure TfrmStructures.edtAddressChange(Sender: TObject);
begin
address:=strtoint('$'+edtaddress.text);
end;
procedure TfrmStructures.TreeView1Expanding(Sender: TObject;
Node: TTreeNode; var AllowExpansion: Boolean);
var s: tstructure;
elementnr: integer;
basestruct: integer;
elementaddress: dword;
i: integer;
begin
AllowExpansion:=true;
s:=tstructure(node.Data);
if s=nil then exit;
if node.getFirstChild<>nil then exit;
elementnr:=node.Index;
//structure and element nr are known, so lets see what it is
basestruct:=s.basestructure;
elementaddress:=s.address;
for i:=0 to elementnr-2 do
inc(elementaddress,definedstructures[basestruct].structelement[i].bytesize);
//make sure it's a pointer
if definedstructures[basestruct].structelement[elementnr].pointerto then
s.objects[elementnr].child:=tstructure.create(treeview1,node,elementaddress,definedstructures[basestruct].structelement[elementnr].structurenr);
currentstructure.refresh;
end;
procedure TfrmStructures.TreeView1MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var tn: ttreenode;
begin
if mbright = button then
begin
tn:=treeview1.GetNodeAt(x,y);
treeview1.Selected:=tn;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -