cheat-engine/Cheat Engine/Tutorial/Unit7.pas
2021-11-22 21:15:37 +01:00

235 lines
7.4 KiB
ObjectPascal
Executable file

unit Unit7;
{$MODE Delphi}
interface
uses
LCLIntf, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, LResources, betterControls;
type
TForm7 = class(TForm)
Memo1: TMemo;
Button2: TButton;
Button1: TButton;
Label1: TLabel;
Button3: TButton;
Label2: TLabel;
SpeedButton1: TSpeedButton;
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure SpeedButton1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form7: TForm7;
i: ^integer;
implementation
uses Unit4, Unit8, frmHelpUnit, cetranslator;
resourcestring
rsWellDoneYouScrewedUpTheTutorial = 'Well done, you screwed up the tutorial!!!!';
rsYouVeGotSecondsLeftToChangeTheValueTo5000 = 'You have %s second%s left to change the value to 5000';
rsStep6PointersPW = 'Step 6: Pointers: (PW=%s)';
rsTryAgain7 = 'So, pointers are too difficult eh? Don''t worry, try again later. For most beginners this is difficult to grasp. But I have to tell you it''s'
+' a powerful feature if you learn to use it. Are you sure you want to quit?';
rsLOSER = 'BOO';
rsTutorialStep6=
'In the previous step I explained how to use the Code finder to handle changing locations. But that method alone '+
'makes it difficult to find the address to set the values you want.'+#13#10+
'That''s why there are pointers:'+#13#10+
''+#13#10+
'At the bottom you''ll find 2 buttons. One will change the value, and the other changes the value AND the location of '+
'the value.'+#13#10+
'For this step you don''t really need to know assembler, but it helps a lot if you do.'+#13#10+
''+#13#10+
'First find the address of the value. When you''ve found it use the function to find out what accesses this address.'+#13#10+
'Change the value again, and an item will show up in the list. Double click that item. (or select and click on more info) and '+
'a new window will open with detailed information on what happened when the instruction ran.'+#13#10+
'If the assembler instruction doesn''t have anything between a ''['' and '']'' then use another item in the list.'+#13#10+
'If it does it will say what it think will be the value of the pointer you need.'+#13#10+
'Go back to the main cheat engine window (you can keep this extra info window open if you want, but if you close it, '+
'remember what is between the ''['' and '']'' ) and do a 4 byte scan in hexadecimal for the value the extra info told you.'+#13#10+
'When done scanning it may return 1 or a few hundred addresses. Most of the time the address you need will be the '+
'smallest one. Now click on the "Add Address Manually" button and select the pointer checkbox.'+#13#10+
''+#13#10+
'The window will change and allow you to type in the address of a pointer and an offset.'+#13#10+
'Fill in the address you just found. It can be in the form: "Tutorial-i386.exe"+xxxxxx (relative to the process), '+#13#10+
'or you can double click the address to add it to the address list and use the absolute address which appears there.'+#13#10+
'If the assembler instruction has a calculation (e.g: [esi+12]) at the end then type the value in that''s at the end above the '+
'address field. This is the offset. Otherwise '+
'leave it 0. If it was a more complicated instruction look at the following calculation.'+#13#10+
''+#13#10+
'Example of a more complicated instruction:'+#13#10+
'[EAX*2+EDX+00000310] eax=4C and edx=00801234.'+#13#10+
'In this case EDX would be the value the pointer has, and EAX*2+00000310 the offset, so the offset you''d fill in '+
'would be 2*4C+00000310=3A8. (This is all in hex, use calc.exe from Windows in Programmer mode to calculate hex values.)'+#13#10+
''+#13#10+
'Back to the tutorial, click OK and the address will be added. If all went right the address will show P->xxxxxxx, with '+
'xxxxxxx being the address of the value you found. If that''s not right, you''ve done something wrong.'+#13#10+
'Now, change the value using the pointer you added in to 5000 and click in the ''Active'' coloumn to freeze it. Then click '+
'Change pointer, and if all went right the Next button will become visible.'+#13#10+
''+#13#10+
''+#13#10+
'extra:'+#13#10+
'You could also use the pointer scanner to find the pointer to this address. https://cheatengine.org/help/pointer-scan.htm';
rsDontFuckingFreezeThePointer = 'I''m sorry, but freezing the pointer is not'
+' really a functional solution';
procedure TForm7.Button2Click(Sender: TObject);
begin
hide;
form8:=tform8.create(self);
form8.left:=left;
form8.top:=top;
form8.width:=width;
form8.height:=height;
form8.show;
end;
procedure TForm7.Button1Click(Sender: TObject);
var j,k,l: integer;
begin
//set new value
j:=i^;
k:=random(1000);
l:=0;
while k=j do
begin
k:=random(1000);
inc(l);
if l=100 then
raise exception.Create(rsWellDoneYouScrewedUpTheTutorial);
end;
i^:=k;
if i^=j then button2.Enabled:=true;
label1.Caption:=IntToStr(i^);
{$O+}
j:=0;
k:=0;
{$O-}
end;
procedure TForm7.Button3Click(Sender: TObject);
var j: integer;
k: integer;
s: string;
oldp: pointer;
begin
button1.Anchors:=[akLeft];
label2.anchors:=[akLeft];
button3.visible:=false;
button3.repaint;
oldp:=i;
getmem(i,4); //don't free else it's too easy
i^:=random(1000);
label1.caption:=IntToStr(i^);
label1.Repaint;
k:=3;
label2.Caption:=IntToStR(k);
label2.Visible:=true;
while k>0 do
begin
if k>1 then
s:='s'
else
s:='';
label2.Caption:=Format(rsYouVeGotSecondsLeftToChangeTheValueTo5000, [IntToStR(k), s]);
label2.Repaint;
sleep(1000);
deC(k);
end;
label2.visible:=false;
//check if it is 5000
if i^=5000 then
begin
if i=oldp then
begin
oldp:=nil;
MessageDlg(rsDontFuckingFreezeThePointer, mtError, [mbok], 0);
end
else
button2.Enabled:=true;
end;
{$O+}
j:=0;
{$O-}
//if j=1 then beep;
button3.visible:=true;
button1.Anchors:=[akLeft, akBottom];
label2.anchors:=[akLeft, akBottom];
end;
procedure TForm7.FormCreate(Sender: TObject);
var k: integer;
begin
k:=1+random(10);
while k>0 do
begin
getmem(i,4); //got to love memory leaks. (but at least it's a good test)
dec(k);
end;
i^:=100;
caption:=altnamer(caption);
memo1.lines.text:=altnamer(rstutorialStep6);
memo1.Lines.Insert(0, Format(rsStep6PointersPW, [inttostr(0)+inttostr(98712)]));
memo1.SelStart:=0;
font.size:=12;
frmHelp.attach(self,'6');
end;
procedure TForm7.FormClose(Sender: TObject; var Action: TCloseAction);
begin
application.Terminate;
end;
procedure TForm7.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
canclose:=MessageDlg(rsTryAgain7, mtconfirmation, [mbyes, mbno], 0)=mryes;
end;
procedure TForm7.SpeedButton1Click(Sender: TObject);
begin
showmessage(rsLOSER);
button2.Click;
end;
initialization
{$i Unit7.lrs}
{$i Unit7.lrs}
end.