cheat-engine/Cheat Engine/Tutorial/Unit9.pas

360 lines
9.8 KiB
ObjectPascal
Raw Permalink Normal View History

2011-07-04 19:52:53 +00:00
unit Unit9;
{$MODE Delphi}
interface
uses
{$ifdef windows}windows, {$endif}LCLIntf, Messages, SysUtils, Classes, Graphics, Controls, Forms,
2021-03-26 00:10:44 +01:00
Dialogs, StdCtrls, Buttons, LResources, betterControls;
2011-07-04 19:52:53 +00:00
type
TForm9 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Memo1: TMemo;
Button2: TButton;
Button1: TButton;
Button3: TButton;
SpeedButton1: TSpeedButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure Button2Click(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
private
{ Private declarations }
procedure relocate;
public
{ Public declarations }
end;
type TLevel4 = record
a: integer;
b: integer;
c: integer;
d: integer;
e: integer;
f: integer;
health: integer;
end;
type PLevel4=^TLevel4;
type TLevel3 = record
p: PLevel4;
a: integer;
b: integer;
c: integer;
d: integer;
e: integer;
f: integer;
end;
type PLevel3=^TLevel3;
type TLevel2 = record
a: integer;
b: integer;
c: integer;
d: integer;
e: integer;
p: PLevel3;
f: integer;
end;
type PLevel2=^TLevel2;
type TLevel1 = record
a: integer;
b: integer;
c: integer;
p: PLevel2;
d: integer;
e: integer;
f: integer;
end;
type PLevel1=^TLevel1;
var
Form9: TForm9;
basepointer: plevel1;
implementation
uses Unit4, Unit10, frmHelpUnit, cetranslator;
2011-07-04 19:52:53 +00:00
2012-01-04 10:31:22 +00:00
resourcestring
rsStep8MultilevelPointersPW = 'Step 8: Multilevel pointers: (PW=%s)';
rsUnrandomizerDetected = 'Unrandomizer detected';
rsYouVeGotSecondsLeftToChangeTheValueTo5000 = 'You''ve got %s seconds left to change the value to 5000';
rsTryAgain9 = 'Aw, you''ve almost reached the end. But don''t worry, multilevel pointers can be a real pain when dealing with. If you get more experienced '
+'someday you can try it again. Are you sure you want to quit?';
2015-12-24 19:26:48 +01:00
rsLOSER = 'BOO';
2012-01-04 10:31:22 +00:00
rsTutorialStep8=
'This step will explain how to use multi-level pointers.'+#13#10+
'In step 6 you had a simple level-1 pointer, with the first address found already being the real base address.'+#13#10+
'This step however is a level-4 pointer. It has a pointer to a pointer to a pointer to a pointer to a pointer to the health.'+#13#10+
''+#13#10+
'You basicly do the same as in step 6. Find out what accesses the value, look at the instruction and what probably is '+
'the base pointer value, and what is the offset, and already fill that in or write it down. But in this case the address '+
'you''ll find will also be a pointer. You just have to find out the pointer to that pointer exactly the same way as you did '+
'with the value. Find out what accesses that address you found, look at the assembler instruction, note the probable '+
2012-01-04 10:31:22 +00:00
'instruction and offset, and use that.'+#13#10+
'And continue till you can''t get any further (usually when the base address is a static address, shown up as green.)'+#13#10+
2012-01-04 10:31:22 +00:00
''+#13#10+
'Click Change Value to let the tutorial access the health.'+#13#10+
'If you think you''ve found the pointer path click Change Register. The pointers and value will then change and you''ll '+
'have 3 seconds to freeze the address to 5000.'+#13#10+
2012-01-04 10:31:22 +00:00
''+#13#10+
'Extra: This problem can also be solved using an auto assembler script, or using the pointer scanner.'+#13#10+
'Extra2: In some situations it is recommended to change CE''s Codefinder settings to Access violations when '+#13#10+
'encountering instructions like mov eax,[eax] since debug registers show it AFTER it was changed, making it hard to '+
'find out the value of the pointer.'+#13#10+
2012-01-04 10:31:22 +00:00
''+#13#10+
''+#13#10+
''+#13#10+
''+#13#10+
''+#13#10+
'Extra3: If you''re still reading. You might notice that when looking at the assembler instructions that the pointer is '+
'being read and filled out in the same codeblock (same routine, if you know assembler, look up till the start of the '+
'routine). This doesn''t always happen, but can be really useful in finding a '+
'pointer when debugging is troublesome.';
2012-01-04 10:31:22 +00:00
2011-07-04 19:52:53 +00:00
procedure TForm9.relocate;
begin
//just adding some more chaos:
if (basepointer<>nil) then
begin
FillChar(basepointer.p.p.p^, sizeof(TLevel4),0); //zeromemory(basepointer.p.p.p,sizeof(TLevel4));
FillChar(basepointer.p.p^,sizeof(TLevel3), 0); //zeromemory(basepointer.p.p,sizeof(TLevel3));
2011-07-04 19:52:53 +00:00
freemem(basepointer.p.p);
FillChar(basepointer.p^,sizeof(TLevel2),0); //zeromemory(basepointer.p,sizeof(TLevel2));
2011-07-04 19:52:53 +00:00
freemem(basepointer.p);
FillChar(basepointer^,sizeof(TLevel1), 0); //zeromemory(basepointer,sizeof(TLevel1));
2011-07-04 19:52:53 +00:00
//delete a chunk inbetween if emptying wasn't enough already
end;
getmem(basepointer,sizeof(TLevel1)+random(128));
basepointer.a:=random(99999);
basepointer.b:=random(99999);
basepointer.c:=random(99999);
basepointer.d:=random(99999);
basepointer.e:=random(99999);
basepointer.f:=random(99999);
getmem(basepointer.p,sizeof(TLevel2)+random(128));
basepointer.p.a:=random(99999);
basepointer.p.b:=random(99999);
basepointer.p.c:=random(99999);
basepointer.p.d:=random(99999);
basepointer.p.e:=random(99999);
basepointer.p.f:=random(99999);
getmem(basepointer.p.p,sizeof(TLevel3)+random(128));
basepointer.p.p.a:=random(99999);
basepointer.p.p.b:=random(99999);
basepointer.p.p.c:=random(99999);
basepointer.p.p.d:=random(99999);
basepointer.p.p.e:=random(99999);
basepointer.p.p.f:=random(99999);
getmem(basepointer.p.p.p,sizeof(TLevel4)+random(128));
basepointer.p.p.p.a:=random(99999);
basepointer.p.p.p.b:=random(99999);
basepointer.p.p.p.c:=random(99999);
basepointer.p.p.p.d:=random(99999);
basepointer.p.p.p.e:=random(99999);
basepointer.p.p.p.f:=random(99999);
end;
procedure TForm9.FormCreate(Sender: TObject);
begin
relocate;
basepointer.p.p.p.health:=random(4000);
label1.caption:=inttostr(basepointer.p.p.p.health);
caption:=altnamer(caption);
memo1.lines.text:=altnamer(rsTutorialStep8);
2012-01-04 10:31:22 +00:00
memo1.Lines.Insert(0, Format(rsStep8MultilevelPointersPW, [inttostr(525)+inttostr(927)]));
2011-07-04 19:52:53 +00:00
memo1.SelStart:=0;
2016-09-05 21:17:11 +02:00
font.size:=12;
2019-07-19 11:27:16 +02:00
frmHelp.attach(self,'8');
2011-07-04 19:52:53 +00:00
end;
procedure TForm9.Button1Click(Sender: TObject);
var h: ^integer;
i: integer;
a: plevel1;
b: plevel2;
c: plevel3;
d: plevel4;
begin
a:=basepointer;
if (a.a=a.b) and (a.b=a.c) and (a.c=a.d) and (a.d=a.e) and (a.e=a.f) then
begin
2012-01-04 10:31:22 +00:00
showmessage(rsUnrandomizerDetected);
2011-07-04 19:52:53 +00:00
exit;
end;
if a.p=nil then exit;
b:=a.p;
if (b.a=b.b) and (b.b=b.c) and (b.c=b.d) and (b.d=b.e) and (b.e=b.f) then
begin
2012-01-04 10:31:22 +00:00
showmessage(rsUnrandomizerDetected);
2011-07-04 19:52:53 +00:00
exit;
end;
if b.p=nil then exit;
c:=b.p;
if (c.a=c.b) and (c.b=c.c) and (c.c=c.d) and (c.d=c.e) and (c.e=c.f) then
begin
2012-01-04 10:31:22 +00:00
showmessage(rsUnrandomizerDetected);
2011-07-04 19:52:53 +00:00
exit;
end;
if c.p=nil then exit;
d:=c.p;
if (d.a=d.b) and (d.b=d.c) and (d.c=d.d) and (d.d=d.e) and (d.e=d.f) then
begin
2012-01-04 10:31:22 +00:00
showmessage(rsUnrandomizerDetected);
2011-07-04 19:52:53 +00:00
exit;
end;
d.health:=random(4000);
label1.caption:=inttostr(d.health);
end;
procedure TForm9.Button3Click(Sender: TObject);
var j: integer;
k: integer;
i: integer;
a: plevel1;
b: plevel2;
c: plevel3;
d: plevel4;
begin
relocate;
a:=basepointer;
if (a.a=a.b) and (a.b=a.c) and (a.c=a.d) and (a.d=a.e) and (a.e=a.f) then
begin
2012-01-04 10:31:22 +00:00
showmessage(rsUnrandomizerDetected);
2011-07-04 19:52:53 +00:00
exit;
end;
if a.p=nil then exit;
b:=a.p;
if (b.a=b.b) and (b.b=b.c) and (b.c=b.d) and (b.d=b.e) and (b.e=b.f) then
begin
2012-01-04 10:31:22 +00:00
showmessage(rsUnrandomizerDetected);
2011-07-04 19:52:53 +00:00
exit;
end;
if b.p=nil then exit;
c:=b.p;
if (c.a=c.b) and (c.b=c.c) and (c.c=c.d) and (c.d=c.e) and (c.e=c.f) then
begin
2012-01-04 10:31:22 +00:00
showmessage(rsUnrandomizerDetected);
2011-07-04 19:52:53 +00:00
exit;
end;
if c.p=nil then exit;
d:=c.p;
if (d.a=d.b) and (d.b=d.c) and (d.c=d.d) and (d.d=d.e) and (d.e=d.f) then
begin
2012-01-04 10:31:22 +00:00
showmessage(rsUnrandomizerDetected);
2011-07-04 19:52:53 +00:00
exit;
end;
d.health:=random(4000);
label1.caption:=inttostr(d.health);
label1.Repaint;
k:=3;
label2.Caption:=IntToStR(k);
label2.Visible:=true;
button1.Anchors:=[akLeft];
label2.anchors:=[akLeft];
button3.visible:=false;
2011-07-04 19:52:53 +00:00
while k>0 do
begin
2012-01-04 10:31:22 +00:00
label2.Caption:=Format(rsYouVeGotSecondsLeftToChangeTheValueTo5000, [IntToStR(k)]);
2011-07-04 19:52:53 +00:00
label2.Repaint;
sleep(1000);
deC(k);
end;
label2.visible:=false;
button3.visible:=true;
button1.Anchors:=[akLeft, akBottom];
label2.anchors:=[akLeft, akBottom];
2011-07-04 19:52:53 +00:00
//check if it is 5000
if d.health=5000 then button2.Enabled:=true;
{$O+}
j:=0;
{$O-}
//if j=1 then beep;
end;
procedure TForm9.FormClose(Sender: TObject; var Action: TCloseAction);
begin
application.Terminate;
end;
procedure TForm9.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
2012-01-04 10:31:22 +00:00
canclose:=MessageDlg(rsTryAgain9, mtconfirmation, [mbyes, mbno], 0)=mryes;
2011-07-04 19:52:53 +00:00
end;
2018-05-29 15:10:22 +02:00
2011-07-04 19:52:53 +00:00
procedure TForm9.Button2Click(Sender: TObject);
begin
2011-07-04 19:52:53 +00:00
hide;
2018-05-29 15:10:22 +02:00
2011-07-04 19:52:53 +00:00
form10:=tform10.create(self);
form10.left:=left;
form10.top:=top;
form10.width:=width;
form10.height:=height;
2011-07-04 19:52:53 +00:00
form10.show;
{ hide;
2011-07-04 19:52:53 +00:00
form4:=tform4.create(self);
form4.show; }
2011-07-04 19:52:53 +00:00
end;
procedure TForm9.SpeedButton1Click(Sender: TObject);
begin
2012-01-04 10:31:22 +00:00
showmessage(rsLOSER);
2011-07-04 19:52:53 +00:00
button2.Click;
end;
initialization
{$i Unit9.lrs}
{$i Unit9.lrs}
end.