cheat-engine/formAddressChangeUnit.pas
cheatengine@gmail.com 4d297adfd2
2011-07-04 19:52:19 +00:00

562 lines
18 KiB
ObjectPascal

unit formAddressChangeUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls,cefuncproc,newkernelhandler,symbolhandler;
type TPointerInfo=record
addresstext:tlabel;
address:Tedit;
offsettext: tlabel;
offset: tedit;
ValueAtAddressText:Tlabel;
FinalDestination: Tlabel;
end;
type
TformAddressChange = class(TForm)
editAddress: TEdit;
Button1: TButton;
Button2: TButton;
cbPointer: TCheckBox;
Label1: TLabel;
BitPanel: TPanel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
Label8: TLabel;
Label9: TLabel;
Label10: TLabel;
Label11: TLabel;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
RadioButton3: TRadioButton;
RadioButton4: TRadioButton;
RadioButton5: TRadioButton;
RadioButton6: TRadioButton;
RadioButton7: TRadioButton;
RadioButton8: TRadioButton;
Label2: TLabel;
Button3: TButton;
Button4: TButton;
Timer1: TTimer;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormShow(Sender: TObject);
procedure cbPointerClick(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure editAddressKeyPress(Sender: TObject; var Key: Char);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
pointerinfo: array of TPointerinfo;
procedure offsetKeyPress(sender: TObject; var key:char);
procedure processaddress;
public
{ Public declarations }
index: integer;
index2: integer;
end;
var
formAddressChange: TformAddressChange;
implementation
uses MainUnit, formsettingsunit;
{$R *.dfm}
procedure Tformaddresschange.processaddress;
var i,j,err,err2: integer;
currentaddress,currentaddress2,currentoffset: dword;
read:dword;
check: boolean;
haserror: boolean;
begin
if length(pointerinfo)=0 then exit;
for i:=length(pointerinfo)-1 downto 0 do
begin
haserror:=false;
currentaddress:=symhandler.getAddressFromName( pointerinfo[i].address.Text, false, haserror);
if haserror then err:=1 else err:=0;
if err>0 then
begin
//everything after this address is wrong
editaddress.text:='????????';
pointerinfo[i].ValueAtAddressText.Caption:='This pointer points to address ????????';
pointerinfo[i].FinalDestination.Caption:='The offset you chose brings it to ????????';
for j:=i-1 downto 0 do
begin
pointerinfo[j].address.text:='Result of next pointer';
pointerinfo[j].ValueAtAddressText.Caption:='This pointer points to address ????????';
pointerinfo[j].FinalDestination.Caption:='The offset you chose brings it to ????????';
end;
exit;
end;
//still here so that address was right
check:=readprocessmemory(processhandle,pointer(currentaddress),@currentaddress2,4,read);
if length(pointerinfo[i].offset.text)>0 then
begin
if pointerinfo[i].offset.text[1]='-' then
val('-$'+copy(pointerinfo[i].offset.text,2,length(pointerinfo[i].offset.text)),currentoffset,err2)
else
val('$'+pointerinfo[i].offset.text,currentoffset,err2);
end else err2:=1;
if (not check) or (read<4) or (err2>0) then
begin
//everything after this address is wrong
if (check) or (read=4) then
pointerinfo[i].ValueAtAddressText.Caption:='This pointer points to address '+IntToHex(currentaddress2,8)
else
pointerinfo[i].ValueAtAddressText.Caption:='This pointer points to address ????????';
pointerinfo[i].FinalDestination.Caption:='The offset you chose brings it to ????????';
editaddress.text:='????????';
for j:=i-1 downto 0 do
begin
pointerinfo[j].address.text:='Result of next pointer';
pointerinfo[j].ValueAtAddressText.Caption:='This pointer points to address ????????';
pointerinfo[j].FinalDestination.Caption:='The offset you chose brings it to ????????';
end;
exit;
end;
//address+offset are correct AND the address is readable
pointerinfo[i].ValueAtAddressText.Caption:='This pointer points to address '+IntToHex(currentAddress2,8);
pointerinfo[i].FinalDestination.Caption:='The offset you chose brings it to '+IntToHex(currentAddress2+currentoffset,8);
if i=0 then
editaddress.text:=IntToHex(currentaddress2+currentoffset,8)
else
pointerinfo[i-1].address.text:=IntToHex(currentaddress2+currentoffset,8);
end;
end;
procedure Tformaddresschange.offsetKeyPress(sender: TObject; var key:char);
begin
if key<>'-' then hexadecimal(key);
if cbpointer.Checked then timer1.Interval:=1;
end;
procedure TformAddressChange.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
action:=cafree;
end;
procedure TformAddressChange.FormShow(Sender: TObject);
var i: integer;
tmp:string;
begin
// if memrec[scrollbar1.position+(sender as TLabel).tag].VarType=5 then //bit
// adr:=inputbox('Address','Give the new address: (use ^ to specify the startbit)',address[(sender as TLabel).tag].caption);
if mainform.memrec[index].IsPointer then
begin
tmp:=mainform.address[index2].Caption;
if tmp='P->????????' then
editaddress.text:='00000000'
else
editaddress.text:=copy(tmp,4,length(tmp));
cbPointer.Checked:=true;
end
else
begin
if mainform.memrec[index].interpretableaddress<>'' then
editaddress.Text:=mainform.memrec[index].interpretableaddress
else
editaddress.Text:=IntToHex(mainform.memrec[index].address,8);
if mainform.memrec[index].VarType=5 then
begin
bitpanel.Visible:=true;
case mainform.memrec[index].Bit of
0: radiobutton1.checked:=true;
1: radiobutton2.checked:=true;
2: radiobutton3.checked:=true;
3: radiobutton4.checked:=true;
4: radiobutton5.checked:=true;
5: radiobutton6.checked:=true;
6: radiobutton7.checked:=true;
7: radiobutton8.checked:=true;
end;
clientwidth:=bitpanel.Left+bitpanel.width;
end else clientwidth:=button4.Left+button4.Width+5;
end;
if mainform.memrec[index].IsPointer then
begin
cbPointer.Checked:=true;
for i:=1 to length(mainform.memrec[index].pointers)-1 do button3.Click; //add lines
//fill the lines
for i:=0 to length(pointerinfo)-1 do
begin
pointerinfo[i].offset.text:=IntToHex(mainform.memrec[index].pointers[i].offset,1);
if i=length(pointerinfo)-1 then
begin
if mainform.memrec[index].pointers[i].Interpretableaddress<>'' then
pointerinfo[i].address.text:=mainform.memrec[index].pointers[i].Interpretableaddress
else
pointerinfo[i].address.text:=IntToHex(mainform.memrec[index].pointers[i].Address,8);
end;
end;
if mainform.memrec[index].pointers[length(mainform.memrec[index].pointers)-1].Interpretableaddress<>'' then
pointerinfo[length(pointerinfo)-1].address.text:=mainform.memrec[index].pointers[length(mainform.memrec[index].pointers)-1].Interpretableaddress;
end;
processaddress;
end;
procedure TformAddressChange.cbPointerClick(Sender: TObject);
var i: integer;
startoffset,inputoffset,rowheight: integer;
begin
if cbpointer.checked then
begin
editAddress.Enabled:=false;
button3.visible:=true;
button4.visible:=true;
//create a address+offset combination and disable the normal address
startoffset:=button3.Top+button3.Height+2;
setlength(pointerinfo,1);
pointerinfo[length(pointerinfo)-1].ValueAtAddressText:=TLabel.Create(self);
with pointerinfo[length(pointerinfo)-1].ValueAtAddressText do
begin
top:=startoffset;
left:=4;
caption:='This pointer points to address ????????.';// The offset you chose brings it to ????????';
showhint:=true;
onkeypress:=offsetKeyPress;
parent:=self;
end;
pointerinfo[length(pointerinfo)-1].FinalDestination:=TLabel.Create(self);
with pointerinfo[length(pointerinfo)-1].FinalDestination do
begin
top:=startoffset;
left:=pointerinfo[length(pointerinfo)-1].ValueAtAddressText.left+pointerinfo[length(pointerinfo)-1].ValueAtAddressText.width+20;
caption:='The offset you chose brings it to ????????';
showhint:=true;
onkeypress:=offsetKeyPress;
parent:=self;
end;
inputoffset:=startoffset+pointerinfo[length(pointerinfo)-1].ValueAtAddressText.height;
pointerinfo[length(pointerinfo)-1].addresstext:=Tlabel.Create(self);
with pointerinfo[length(pointerinfo)-1].addresstext do
begin
top:=inputoffset+2;
left:=4;
caption:='Address of pointer';
parent:=self;
end;
pointerinfo[length(pointerinfo)-1].address:=TEdit.create(self);
with pointerinfo[length(pointerinfo)-1].address do
begin
top:=inputoffset;
left:=pointerinfo[length(pointerinfo)-1].addresstext.left+pointerinfo[length(pointerinfo)-1].addresstext.width+3;
width:=105;
onkeypress:=editAddress.onkeypress;
parent:=self;
end;
pointerinfo[length(pointerinfo)-1].offsettext:=Tlabel.create(self);
with pointerinfo[length(pointerinfo)-1].offsettext do
begin
top:=inputoffset+2;
left:=pointerinfo[length(pointerinfo)-1].FinalDestination.left;
caption:='Offset (Hex)';
parent:=self;
end;
pointerinfo[length(pointerinfo)-1].offset:=TEdit.create(self);
with pointerinfo[length(pointerinfo)-1].offset do
begin
top:=inputoffset;
left:=pointerinfo[length(pointerinfo)-1].offsettext.left+pointerinfo[length(pointerinfo)-1].offsettext.width+5;
width:=70;
text:='0';
hint:='Fill in the nr. of bytes after the location the pointer points to';
showhint:=true;
onkeypress:=offsetKeyPress;
parent:=self;
end;
clientwidth:=pointerinfo[length(pointerinfo)-1].FinalDestination.left+pointerinfo[length(pointerinfo)-1].FinalDestination.width+5;
height:=height+66;
end
else
begin
if mainform.memrec[index].VarType=5 then
begin
bitpanel.Visible:=true;
clientwidth:=bitpanel.left+bitpanel.Width+5;
end else clientwidth:=editaddress.Left+editaddress.Width+5;
clientheight:=cbPointer.Top+cbPointer.Height+8+button1.Height+8;
editaddress.enabled:=true;
button3.visible:=false;
button4.visible:=false;
for i:=0 to length(PointerInfo)-1 do
begin
pointerinfo[i].addresstext.free;
pointerinfo[i].address.Free;
pointerinfo[i].offsettext.Free;
pointerinfo[i].offset.Free;
pointerinfo[i].ValueAtAddressText.Free;
pointerinfo[i].FinalDestination.Free;
end;
setlength(pointerinfo,0);
end;
end;
procedure TformAddressChange.Button4Click(Sender: TObject);
var
rowheight: integer;
i: integer;
oldmethod: boolean;
begin
if length(pointerinfo)=1 then cbPointer.checked:=false
else
begin
rowheight:=pointerinfo[length(pointerinfo)-1].ValueAtAddressText.height;
rowheight:=rowheight+pointerinfo[length(pointerinfo)-1].address.height;
inc(rowheight,2);
pointerinfo[length(pointerinfo)-2].address.enabled:=true;
oldmethod:=formsettings.cbOldPointerAddMethod.checked;
if (((GetKeyState(VK_CONTROL) shr 15) and 1)=1) then oldmethod:=not oldmethod;
if not oldmethod then
begin
pointerinfo[length(pointerinfo)-2].address.text:=pointerinfo[length(pointerinfo)-1].address.text;
for i:=0 to length(pointerinfo)-2 do
pointerinfo[i].offset.text:=pointerinfo[i+1].offset.text;
end
else
pointerinfo[length(pointerinfo)-2].address.text:='';
pointerinfo[length(pointerinfo)-1].addresstext.free;
pointerinfo[length(pointerinfo)-1].address.free;
pointerinfo[length(pointerinfo)-1].offsettext.free;
pointerinfo[length(pointerinfo)-1].offset.free;
pointerinfo[length(pointerinfo)-1].valueataddresstext.free;
pointerinfo[length(pointerinfo)-1].FinalDestination.free;
setlength(pointerinfo,length(pointerinfo)-1);
height:=height-rowheight;
end;
end;
procedure TformAddressChange.Button3Click(Sender: TObject);
var
rowheight: integer;
i: integer;
oldaddress: string;
oldmethod: boolean;
begin
rowheight:=pointerinfo[length(pointerinfo)-1].ValueAtAddressText.height;
rowheight:=rowheight+pointerinfo[length(pointerinfo)-1].address.height;
inc(rowheight,2);
oldaddress:=pointerinfo[length(pointerinfo)-1].address.text;
pointerinfo[length(pointerinfo)-1].address.text:='result of next pointer';
pointerinfo[length(pointerinfo)-1].address.enabled:=false;
setlength(pointerinfo,length(pointerinfo)+1);
pointerinfo[length(pointerinfo)-1].addresstext:=Tlabel.Create(self);
with pointerinfo[length(pointerinfo)-1].addresstext do
begin
top:=pointerinfo[length(pointerinfo)-2].addresstext.top+rowheight;
left:=4;
caption:='Address of pointer';
parent:=self;
end;
pointerinfo[length(pointerinfo)-1].address:=TEdit.create(self);
with pointerinfo[length(pointerinfo)-1].address do
begin
top:=pointerinfo[length(pointerinfo)-2].address.top+rowheight;
left:=pointerinfo[length(pointerinfo)-2].address.left;
width:=105;
onkeypress:=editAddress.onkeypress;
parent:=self;
end;
pointerinfo[length(pointerinfo)-1].offsettext:=Tlabel.create(self);
with pointerinfo[length(pointerinfo)-1].offsettext do
begin
top:=pointerinfo[length(pointerinfo)-2].offsettext.top+rowheight;
left:=pointerinfo[length(pointerinfo)-2].offsettext.left;
caption:='Offset (Hex)';
parent:=self;
end;
pointerinfo[length(pointerinfo)-1].offset:=TEdit.create(self);
with pointerinfo[length(pointerinfo)-1].offset do
begin
top:=pointerinfo[length(pointerinfo)-2].offset.top+rowheight;
left:=pointerinfo[length(pointerinfo)-2].offset.left;
width:=70;
text:='0';
hint:='Fill in the nr. of bytes after the location the pointer points to';
showhint:=true;
onkeypress:=offsetKeyPress;
parent:=self;
end;
pointerinfo[length(pointerinfo)-1].ValueAtAddressText:=TLabel.Create(self);
with pointerinfo[length(pointerinfo)-1].ValueAtAddressText do
begin
top:=pointerinfo[length(pointerinfo)-2].ValueAtAddressText.top+rowheight;
left:=pointerinfo[length(pointerinfo)-2].ValueAtAddressText.left;
caption:='This pointer points to address ????????.';// The offset you chose brings it to ????????';
showhint:=true;
onkeypress:=offsetKeyPress;
parent:=self;
end;
pointerinfo[length(pointerinfo)-1].FinalDestination:=TLabel.Create(self);
with pointerinfo[length(pointerinfo)-1].FinalDestination do
begin
top:=pointerinfo[length(pointerinfo)-2].FinalDestination.top+rowheight;
left:=pointerinfo[length(pointerinfo)-2].FinalDestination.left;
caption:='The offset you chose brings it to ????????';
showhint:=true;
onkeypress:=offsetKeyPress;
parent:=self;
end;
oldmethod:=formsettings.cbOldPointerAddMethod.checked;
if (((GetKeyState(VK_CONTROL) shr 15) and 1)=1) then oldmethod:=not oldmethod;
if not oldmethod then
begin
for i:=length(pointerinfo)-1 downto 1 do
pointerinfo[i].offset.Text:=pointerinfo[i-1].offset.text;
pointerinfo[0].offset.Text:='0';
pointerinfo[length(pointerinfo)-1].address.Text:=oldaddress;
end;
height:=height+rowheight;
end;
procedure TformAddressChange.Button1Click(Sender: TObject);
var bit: integer;
address: dword;
err:integer;
paddress: dword;
offsets: array of integer;
i: integer;
begin
if RadioButton1.checked then bit:=0 else
if RadioButton2.checked then bit:=1 else
if RadioButton3.checked then Bit:=2 else
if RadioButton4.checked then Bit:=3 else
if RadioButton5.checked then Bit:=4 else
if RadioButton6.checked then Bit:=5 else
if RadioButton7.checked then Bit:=6 else
Bit:=7;
if cbpointer.Checked then
begin
address:=0;
paddress:=symhandler.getaddressfromname(pointerinfo[length(pointerinfo)-1].address.text);
end
else
begin
paddress:=0;
addresS:=symhandler.getaddressfromname(editaddress.text);
end;
setlength(offsets,length(pointerinfo));
for i:=0 to length(pointerinfo)-1 do
begin
if length(pointerinfo[i].offset.Text)>0 then
begin
if pointerinfo[i].offset.Text[1]='-' then
val('-$'+copy(pointerinfo[i].offset.Text,2,length(pointerinfo[i].offset.Text)-1),offsets[i],err)
else
val('$'+pointerinfo[i].offset.Text,offsets[i],err);
if err<>0 then raise exception.Create(pointerinfo[i].offset.Text+' is not a valid offset');
end else raise exception.Create('Not all offsets have been filled in');
end;
mainform.memrec[index].Address:=address;
mainform.memrec[index].Bit:=bit;
setlength(mainform.memrec[index].pointers,length(offsets));
for i:=0 to length(offsets)-1 do
begin
mainform.memrec[index].pointers[i].Address:=paddress;
mainform.memrec[index].pointers[i].offset:=offsets[i];
end;
mainform.memrec[index].IsPointer:=cbpointer.Checked;
mainform.memrec[index].Frozen:=false;
if mainform.memrec[index].ispointer then
mainform.memrec[index].pointers[length(mainform.memrec[index].pointers)-1].Interpretableaddress:=pointerinfo[length(pointerinfo)-1].address.text
else
mainform.memrec[index].interpretableaddress:=editaddress.text;
modalresult:=mrok;
end;
procedure TformAddressChange.editAddressKeyPress(Sender: TObject;
var Key: Char);
begin
hexadecimal(key);
if cbpointer.Checked then timer1.Interval:=1;
end;
procedure TformAddressChange.Timer1Timer(Sender: TObject);
begin
timer1.Interval:=1000;
if visible and cbpointer.checked then
processaddress;
end;
end.