root/Cheat Engine/AdvancedOptionsUnit.pas @ 307

Revision 307, 26.3 kB (checked in by dark_byte, 8 months ago)

fixed advanced options no rightclick browse and marking changed entries red

Line 
1unit AdvancedOptionsUnit;
2
3interface
4
5uses
6  symbolhandler,tlhelp32,Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7  Dialogs, StdCtrls, Buttons,debugger, Menus,cefuncproc, ExtCtrls,disassembler,
8  SyncObjs,registry, ComCtrls{$ifdef net},netapis{$else},newkernelhandler{$endif};
9
10
11
12type
13  TAdvancedOptions = class(TForm)
14    PopupMenu2: TPopupMenu;
15    CC1: TMenuItem;
16    CC2: TMenuItem;
17    Remove1: TMenuItem;
18    Rename1: TMenuItem;
19    Findoutwhatthiscodechanges1: TMenuItem;
20    Openthedisassemblerhere1: TMenuItem;
21    Findthiscodeinsideabinaryfile1: TMenuItem;
22    OpenDialog1: TOpenDialog;
23    N1: TMenuItem;
24    N2: TMenuItem;
25    SaveDialog1: TSaveDialog;
26    Replaceall1: TMenuItem;
27    Timer1: TTimer;
28    Panel1: TPanel;
29    Button1: TButton;
30    Button4: TButton;
31    Button2: TButton;
32    Panel2: TPanel;
33    Pausebutton: TSpeedButton;
34    SaveButton: TSpeedButton;
35    Label1: TLabel;
36    N3: TMenuItem;
37    Codelist2: TListView;
38    procedure FormShow(Sender: TObject);
39    procedure PopupMenu2Popup(Sender: TObject);
40    procedure CC2Click(Sender: TObject);
41    procedure CC1Click(Sender: TObject);
42    procedure Remove1Click(Sender: TObject);
43    procedure Findoutwhatthiscodechanges1Click(Sender: TObject);
44    procedure Rename1Click(Sender: TObject);
45    procedure Findthiscodeinsideabinaryfile1Click(Sender: TObject);
46    procedure Button1Click(Sender: TObject);
47    procedure SaveButtonClick(Sender: TObject);
48    procedure PausebuttonClick(Sender: TObject);
49    procedure PausebuttonMouseMove(Sender: TObject; Shift: TShiftState; X,
50      Y: Integer);
51    procedure Replaceall1Click(Sender: TObject);
52    procedure Timer1Timer(Sender: TObject);
53    procedure Button4Click(Sender: TObject);
54    procedure FormCreate(Sender: TObject);
55    procedure Button2Click(Sender: TObject);
56    procedure Panel1Resize(Sender: TObject);
57    procedure Codelist2DblClick(Sender: TObject);
58    procedure Panel2Resize(Sender: TObject);
59    procedure Codelist2CustomDrawItem(Sender: TCustomListView;
60      Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
61  private
62    { Private declarations }
63    plabel:string;
64
65    red: boolean;
66
67    procedure hotkey(var Message: TMessage); message WM_HOTKEY;
68  public
69    { Public declarations }
70    pausehotkeystring: string;
71    pausedbyhotkey: boolean;
72
73    reader: boolean;
74    numberofcodes: integer;
75    code: array of record
76            before: array of byte;
77            actualopcode: array of byte;
78            after: array of byte;
79            changed:boolean;
80            modulename: string;
81            offset: dword;
82            Address: dword; //in case module offsets dont work
83          end;
84
85    function AddToCodeList(address: dword; sizeofopcode: integer;changed: boolean; multiadd: boolean=false):boolean;
86    procedure UpdateAdvancedOptions;
87  end;
88
89procedure unpause;
90
91var
92  AdvancedOptions: TAdvancedOptions;
93
94resourcestring
95  strnotreadable='This address is not readable';
96  strNotWhatitshouldbe='The memory at this address is''nt what it should be! Continue?';
97
98implementation
99
100uses {$ifdef net}ceclient,unit2{$else}MainUnit, MemoryBrowserFormUnit{$endif},
101  inputboxtopunit,
102  {$ifndef net}
103  formChangedAddresses,
104  formhotkeyunit,
105  frmDissectwindowUnit,
106  frmCapturedTimersUnit,
107  frmDirectXUnit,
108//  frmOpenglUnit,
109  {$endif}
110  frmFindCodeInFileUnit,
111  standaloneunit,
112  formsettingsunit,
113  mainunit2;
114
115
116
117{$R *.dfm}
118
119procedure unpause;
120begin
121  if advancedoptions.Pausebutton.Down then
122  begin
123    advancedoptions.Pausebutton.Down:=false;
124    advancedoptions.Pausebutton.Click;
125  end;
126end;
127
128
129procedure TAdvancedOptions.hotkey(var Message: TMessage);
130begin
131  if Message.wparam=0 then  //pause
132  begin
133    pausebutton.down:=not pausebutton.down;
134    pausebutton.Click;
135  end;
136end;
137
138procedure TadvancedOptions.UpdateAdvancedOptions;
139begin
140
141end;
142
143
144function TAdvancedOptions.AddToCodeList(address: dword; sizeofopcode: integer;changed: boolean; multiadd: boolean=false):boolean;
145resourcestring
146  stralreadyinthelist = 'This byte is already part of another opcode already present in the list';
147  strPartOfOpcodeInTheList='At least one of these bytes is already in the list';
148  strAddressAlreadyInTheList='This address is already in the list';
149  strCECode='Cheat Engine code:';
150  strNameCECode='What name do you want to give this code?';
151  strChangeOf='Change of ';
152  strCode='Code :';
153var i: integer;
154    bread: dword;
155    toread,toread2: dword;
156    backupbytes: array[0..4] of byte;
157    ignore: string;
158    address2:dword;
159
160    starta,stopa,startb,stopb: dword;
161    modulename,modulebaseaddress:dword;
162
163    ths: thandle;
164    me32:MODULEENTRY32;
165    x: pchar;
166    canceled: boolean;
167    D,newstring: string;
168    li: tlistitem;
169begin
170  //check if the address is already in the list
171  for i:=0 to numberofcodes-1 do
172  begin
173    //if (code[i].Address=address) then raise exception.create(strAddressAlreadyInTheList);
174
175    //I want to see if address to address+sizeofopcode-1 is overlapping with addresses[i] to length(actualopcode[i])-1
176    starta:=code[i].Address;
177    stopa:=code[i].Address+length(code[i].actualopcode)-1;
178
179    startb:=address;
180    stopb:=address+sizeofopcode-1;
181
182    if ((starta>startb) and (starta<stopb)) or
183       ((startb>starta) and (startb<stopa)) then
184      if sizeofopcode=1 then
185        raise exception.Create(stralreadyinthelist)
186      else
187        raise exception.Create(strPartOfOpcodeInTheList);
188
189  end;
190
191
192  address2:=address;
193
194
195  d:=disassemble(address2,ignore);
196  splitDisassembledString(d, false, ignore,ignore,d,ignore);
197
198  if changed then
199    newstring:=strChangeOf+d
200  else
201    newstring:=strCode+d;
202
203  if not multiadd then
204  begin
205    newstring:=Inputboxtop(strCECode,strNameCECode, newstring,true,canceled)
206  end
207  else
208  begin
209    canceled:=false;
210
211  end;
212
213
214  result:=not canceled;
215
216  if not result then exit;
217
218  if newstring='' then newstring:=strNoDescription;
219
220
221  inc(numberofcodes);
222  setlength(advancedoptions.code,numberofcodes);
223
224  //before
225  bread:=0;
226  toread:=5;
227  toread2:=5;
228  while bread<toread do
229  begin
230    toread:=toread2;
231    readprocessmemory(processhandle,pointer(address-5+(5-toread)),addr(backupbytes[0]),toread,bread);
232    if bread=toread then
233    begin
234
235      setlength(AdvancedOptions.code[numberofcodes-1].before,toread);
236      for i:=0 to toread-1 do AdvancedOptions.code[numberofcodes-1].before[i]:=backupbytes[i];
237    end;
238    dec(toread2);
239  end;
240
241  //actualopcode
242
243  setlength(AdvancedOptions.code[numberofcodes-1].actualopcode,sizeofopcode);
244  readprocessmemory(processhandle,pointer(address),addr(AdvancedOptions.code[numberofcodes-1].actualopcode[0]),sizeofopcode,bread);
245
246  //after
247  readprocessmemory(processhandle,pointer(address+sizeofopcode),@backupbytes[0],5,bread);
248
249  setlength(AdvancedOptions.code[numberofcodes-1].after,bread);
250  for i:=0 to bread-1 do AdvancedOptions.code[numberofcodes-1].after[i]:=backupbytes[i];
251
252  code[numberofcodes-1].changed:=changed;
253  code[numberofcodes-1].Address:=address;
254  code[numberofcodes-1].modulename:='';
255  code[numberofcodes-1].offset:=0;
256
257  //get the module this code is in
258  ths:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,processid);
259  me32.dwSize:=sizeof(MODULEENTRY32);
260  if ths<>0 then
261  begin
262    try
263      if module32first(ths,me32) then
264      repeat
265        if (address>=dword(me32.modBaseAddr)) and (address<dword(me32.modBaseAddr)+me32.modBaseSize) then
266        begin
267          x:=me32.szExePath;
268          code[numberofcodes-1].modulename:=extractfilename(x);
269          code[numberofcodes-1].offset:=address-dword(me32.modBaseAddr);
270          break;
271        end;
272      until not module32next(ths,me32);
273    finally
274      closehandle(ths);
275    end;
276  end;
277
278  li:=self.Codelist2.Items.Add;
279
280  if code[numberofcodes-1].modulename<>'' then
281    li.Caption:=code[numberofcodes-1].modulename+'+'+inttohex(code[numberofcodes-1].offset,1)
282  else
283    li.Caption:=inttohex(address,8);
284
285  li.SubItems.Add(newstring);
286end;
287
288
289procedure TAdvancedOptions.FormShow(Sender: TObject);
290begin
291
292  UpdateAdvancedOptions;
293end;
294
295procedure TAdvancedOptions.PopupMenu2Popup(Sender: TObject);
296var offset: dword;
297    opcode,desc: string;
298    fb,nb: integer;
299    seperator: integer;
300
301    mi: tmoduleinfo;
302resourcestring
303  strFindWhatCodeaccesses='Find out what addresses this code accesses';
304  strFindWhatCodeReads='Find out what addresses this code reads from';
305  strFindWhatCodeWrites='Find out what addresses this code writes to';
306begin
307  if (codelist2.Items.Count=0) or (codelist2.ItemIndex=-1) then
308  begin
309    cc1.visible:=false;
310    cc2.visible:=false;
311    rename1.visible:=false;
312    remove1.Visible:=false;
313    Openthedisassemblerhere1.Visible:=false;
314    Findoutwhatthiscodechanges1.visible:=false;
315    Findthiscodeinsideabinaryfile1.Visible:=false;
316    Replaceall1.Visible:=false;
317  end else
318  begin
319    rename1.visible:=true;
320    remove1.visible:=true;
321
322    Replaceall1.Visible:=true;
323    Openthedisassemblerhere1.visible:=true;
324    Findthiscodeinsideabinaryfile1.Visible:=true;
325
326    if code[codelist2.itemindex].modulename<>'' then
327    begin
328      symhandler.getmodulebyname(code[codelist2.itemindex].modulename,mi);
329      code[codelist2.itemindex].Address:=mi.baseaddress+code[codelist2.itemindex].offset;
330    end;
331
332    if code[codelist2.itemindex].changed then
333    begin
334      cc1.visible:=false;
335      cc2.visible:=true;
336      Findoutwhatthiscodechanges1.visible:=false;
337    end else
338    begin
339      cc1.visible:=true;
340      cc2.visible:=false;
341
342      //disassemble this address, and see if it a writer or reader
343      //if neither grey it out
344      offset:=code[codelist2.itemindex].Address;
345      opcode:=disassemble(offset,desc);
346
347      Findoutwhatthiscodechanges1.Caption:=strFindWhatCodeAccesses;
348      Findoutwhatthiscodechanges1.enabled:=false;
349      fb:=pos('[',opcode);
350      if fb>0 then
351      begin
352        nb:=pos(']',opcode);
353        if nb>fb then //just a simple check to verify the opcode is ok
354        begin
355          seperator:=pos(',',opcode);
356          if seperator>-1 then
357          begin
358            if seperator<fb then //reader
359            begin
360              reader:=true;
361              FindOutWhatThisCodeChanges1.caption:=strFindWhatCodeReads
362            end
363            else
364            begin
365              reader:=false;
366              FindOutWhatThisCodeChanges1.caption:=strfindwhatcodewrites;
367            end;
368
369
370            Findoutwhatthiscodechanges1.enabled:=true;
371          end;
372        end;
373      end;
374
375
376      Findoutwhatthiscodechanges1.visible:=true;
377    end;
378  end;
379
380  {$ifdef net}
381  Findoutwhatthiscodechanges1.Visible:=false;
382
383
384  {$endif}
385
386end;
387
388procedure TAdvancedOptions.CC2Click(Sender: TObject);
389var i,j: integer;
390    a,original,written: dword;
391    lengthactualopcode: dword;
392    temp: array of byte;
393    temp2: array of byte;
394
395resourcestring strcouldntrestorecode='Error when trying to restore this code!';
396               strnotthesame='The memory at this address isn''t what it should be! Continue?';
397begin
398  for i:=0 to codelist2.items.Count-1 do
399  begin
400
401    if not codelist2.Items[i].Selected then continue;
402
403    lengthactualopcode:=length(code[i].actualopcode);
404    //read the current list, if it isnt a NOP or the actualopcode give a warning
405    setlength(temp,lengthactualopcode);
406    setlength(temp2,lengthactualopcode);
407    for j:=0 to lengthactualopcode-1 do
408      temp[j]:=$90;
409
410    readprocessmemory(processhandle,pointer(code[i].Address),@temp2[0],lengthactualopcode,original);
411    if original<>lengthactualopcode then
412      raise exception.Create(strNotReadable);
413
414    //check if it is a nop field
415    if not comparemem(@temp[0],@temp2[0],lengthactualopcode) then
416    begin
417      //NO????????
418
419      //then check if it is the actual opcode, and there was a bug
420      if not comparemem(@temp[0],@code[i].actualopcode[0],lengthactualopcode) then
421      begin
422        //It's also not the original opcode? WTF, This dude must be braindeath...
423        if messagedlg(strnotthesame,mtWarning,[mbyes,mbno],0)=mrno then exit;
424      end
425      else
426      begin
427        code[i].changed:=false;
428        codelist2.Repaint;
429        exit;
430      end;
431    end;
432
433
434    //set to read and write
435    VirtualProtectEx(processhandle,pointer(code[i].Address),length(code[i].actualopcode),PAGE_EXECUTE_READWRITE,original);  //I want to execute this, read it and write it. (so, full access)
436
437    //write
438    writeprocessmemory(processhandle,pointer(code[i].Address),@code[i].actualopcode[0],length(code[i].actualopcode),written);
439    if written<>lengthactualopcode then
440    begin
441      messagedlg(strCouldntrestorecode,mtWarning,[MBok],0);
442      VirtualProtectEx(processhandle,pointer(code[i].Address),lengthactualopcode,original,a);  //ignore a
443      exit;
444    end;
445
446    //set back
447    VirtualProtectEx(processhandle,pointer(code[i].Address),lengthactualopcode,original,a);  //ignore a
448    FlushInstructionCache(processhandle,pointer(code[i].Address),lengthactualopcode);
449
450    code[i].changed:=false;
451  end;
452
453  codelist2.Repaint;
454
455end;
456
457procedure TAdvancedOptions.CC1Click(Sender: TObject);
458var codelength: integer;
459    written: dword;
460    i,index: integer;
461    nops: array of byte;
462    a,b: dword;
463    original: dword;
464resourcestring strcouldntwrite='The memory at this address couldn''t be written';
465begin
466  //search dselected in the addresslist
467  for index:=0 to codelist2.items.Count-1 do
468  begin
469    if not codelist2.items[index].Selected then continue;
470
471    a:=code[index].Address;
472    codelength:=length(code[index].actualopcode);
473
474    //read the opcode currently at the address
475    setlength(nops,codelength);
476    readprocessmemory(processhandle,pointer(a),@nops[0],codelength,b);
477    if b<>dword(codelength) then
478      raise exception.Create(strNotReadable);
479
480    //compare it with what is in the actualopcode array
481    if not comparemem(@nops[0],@code[index].actualopcode[0],codelength) then
482      if messagedlg(strNotWhatitshouldbe,mtWarning,[mbyes,mbno],0)=mrno then exit;
483
484
485
486    for i:=0 to codelength-1 do
487      nops[i]:=$90;  //$90=nop
488
489   // get old security and set new security
490    VirtualProtectEx(processhandle,pointer(a),codelength,PAGE_EXECUTE_READWRITE,original);  //I want to execute this, read it and write it. (so, full access)
491
492    writeprocessmemory(processhandle,pointer(a),@nops[0],codelength,written);
493    if written<>dword(codelength) then
494    begin
495      messagedlg(strcouldntwrite,mtError,[mbok],0);
496      exit;
497    end;
498
499
500    //set old security back
501    VirtualProtectEx(processhandle,pointer(a),codelength,original,a);  //ignore a
502
503    FlushInstructionCache(processhandle,pointer(a),codelength);
504
505    code[index].changed:=true;
506  end;
507  codelist2.Repaint;
508end;
509
510procedure TAdvancedOptions.Remove1Click(Sender: TObject);
511var i,j,index: integer;
512  multidelete: boolean;
513begin
514  codelist2.Items.BeginUpdate;
515  multidelete:=codelist2.SelCount>1;
516  while codelist2.SelCount>0 do
517  begin
518    index:=codelist2.Selected.Index;
519    if (index=-1) or (codelist2.Items.Count=0) then exit;
520
521    if not multidelete then
522      if messagedlg('Delete '+codelist2.Items[index].SubItems[0]+' ?',mtConfirmation,[mbyes,mbno],0) = mrno then exit;
523
524
525    setlength(code[index].before,0);
526    setlength(code[index].actualopcode,0);
527    setlength(code[index].after,0);
528
529    for i:=index to numberofcodes-2 do
530    begin
531      code[i].before:=code[i+1].before;
532      code[i].actualopcode:=code[i+1].actualopcode;
533      code[i].after:=code[i+1].after;
534      code[i].Address:=code[i+1].Address;
535      code[i].changed:=code[i+1].changed;
536      code[i].modulename:=code[i+1].modulename;
537      code[i].offset:=code[i+1].offset;
538    end;
539
540    dec(numberofcodes);
541    setlength(code,numberofcodes);
542
543    codelist2.Items.Delete(index);
544  end;
545  codelist2.Items.endUpdate;
546end;
547
548procedure TAdvancedOptions.Findoutwhatthiscodechanges1Click(
549  Sender: TObject);
550begin
551  MemoryBrowser.FindWhatThisCodeAccesses(code[codelist2.ItemIndex].Address);
552
553end;
554
555procedure TAdvancedOptions.Rename1Click(Sender: TObject);
556var index: integer;
557begin
558  index:=codelist2.ItemIndex;
559  codelist2.Items[index].SubItems[0]:=inputbox('New name','Give the new name of this entry',codelist2.Items[index].SubItems[0]);
560end;
561
562procedure TAdvancedOptions.Findthiscodeinsideabinaryfile1Click(
563  Sender: TObject);
564begin
565  formFindCodeInFile:=TformFindCodeInFile.create(self);
566  if formFindcodeInfile.ok then formFindCodeInFile.showmodal;
567end;
568
569procedure TAdvancedOptions.Button1Click(Sender: TObject);
570begin
571  close;
572end;
573
574procedure TAdvancedOptions.SaveButtonClick(Sender: TObject);
575begin
576  StandAlone.filename:=SaveDialog1.filename;
577  standAlone.showmodal;
578end;
579
580procedure TAdvancedOptions.PausebuttonClick(Sender: TObject);
581var i: integer;
582    ct: _Context;
583begin
584  {$ifndef net}
585
586  if hypermode<>nil then
587  begin
588    pausebutton.down:=not pausebutton.down;
589    exit;
590  end;
591
592  if processhandle=0 then
593  begin
594    pausebutton.down:=false;
595    exit;
596  end;
597
598
599  if pausebutton.down then
600  begin
601    if processid=getcurrentprocessid then
602    begin
603      pausebutton.down:=false;
604      exit;
605    end;
606
607
608    if (debuggerthread=nil) and (@ntsuspendprocess<>nil) then
609    begin
610      if ntsuspendprocess(processhandle)<>0 then //failed somehow, try the debugger from now on
611      begin
612        @ntsuspendprocess:=nil;
613        pausebuttonclick(sender);
614        exit;
615      end;
616    end
617    else
618    begin
619      if not startdebuggerifneeded(not pausedbyhotkey) then
620      begin
621        pausebutton.Down:=false;
622        exit;
623      end;
624
625
626
627      debuggerthread.Suspend;
628      for i:=0 to length(debuggerthread.threadlist)-1 do
629        suspendthread(debuggerthread.threadlist[i][1]);
630    end;
631    pausebutton.Hint:='Resume the game'+pausehotkeystring;
632    pausebutton.down:=true;
633
634    red:=false;
635    mainform.ProcessLabel.font.Color:=clred;
636
637    plabel:=mainform.ProcessLabel.Caption;
638    mainform.ProcessLabel.Caption:=mainform.ProcessLabel.Caption+' (paused)';
639    timer1.Enabled:=true;
640  end
641  else
642  begin
643    //resume
644    if (debuggerthread=nil) and (@ntresumeprocess<>nil) then
645    begin
646      ntresumeprocess(processhandle);
647    end
648    else
649    begin
650      for i:=length(debuggerthread.threadlist)-1 downto 0 do
651        resumethread(debuggerthread.threadlist[i][1]);
652
653      debuggerthread.Resume;
654    end;
655
656    pausebutton.Hint:='Pause the game'+pausehotkeystring;
657
658    timer1.Enabled:=false;
659    mainform.ProcessLabel.Font.Color:=clMenuText;
660    mainform.ProcessLabel.Caption:=plabel;
661
662
663    pausebutton.Down:=false;
664  end;
665
666  {$else}
667  //network version
668  if pausebutton.down then
669  begin
670    if not startdebuggerifneeded then
671    begin
672      pausebutton.Down:=false;
673      exit;
674    end;
675
676    output[0]:=CS_SuspenProcess;
677    sendbuf(1);
678    pausebutton.Hint:='Resume the game'+pausehotkeystring;
679    pausebutton.down:=true;
680  end
681  else
682  begin
683    output[0]:=CS_ResumeProcess;
684    sendbuf(1);
685    pausebutton.Hint:='Pause the game';
686    pausebutton.Down:=false;
687  end;
688{$endif}
689end;
690
691procedure TAdvancedOptions.PausebuttonMouseMove(Sender: TObject;
692  Shift: TShiftState; X, Y: Integer);
693begin
694  if pausebutton.Down then
695    pausebutton.hint:='Resume the game'+pausehotkeystring
696  else
697    pausebutton.hint:='Pause the game'+pausehotkeystring;
698end;
699
700procedure TAdvancedOptions.Replaceall1Click(Sender: TObject);
701var codelength: integer;
702    written: dword;
703    j,i,index: integer;
704    nops: array of byte;
705    a,b: dword;
706    original: dword;
707    mi: TModuleInfo;
708begin
709  //search dselected in the addresslist
710  for j:=0 to codelist2.Items.Count-1 do
711  begin
712    index:=j;
713    if code[index].changed then continue;
714
715    if code[index].modulename<>'' then //update modulebase
716    begin
717      symhandler.getmodulebyname(code[index].modulename,mi);
718      code[index].Address:=mi.baseaddress+code[index].offset;
719    end;
720
721
722    a:=code[index].Address;
723    codelength:=length(code[index].actualopcode);
724
725    //read the opcode currently at the address
726    setlength(nops,codelength);
727    readprocessmemory(processhandle,pointer(a),@nops[0],codelength,b);
728    if b<>dword(codelength) then
729      raise exception.Create(strNotReadable);
730
731    //compare it with what is in the actualopcode array
732    if not comparemem(@nops[0],@code[index].actualopcode[0],codelength) then
733      if messagedlg(strNotWhatitshouldbe,mtWarning,[mbyes,mbno],0)=mrno then exit;
734
735    //-------
736
737
738
739    for i:=0 to codelength-1 do
740      nops[i]:=$90;  //$90=nop
741
742   // get old security and set new security
743    VirtualProtectEx(processhandle,pointer(a),codelength,PAGE_EXECUTE_READWRITE,original);  //I want to execute this, read it and write it. (so, full access)
744
745    writeprocessmemory(processhandle,pointer(a),@nops[0],codelength,written);
746    if written<>dword(codelength) then
747    begin
748      messagedlg('The memory at this address couldn''t be written',mtError,[mbok],0);
749      exit;
750    end;
751
752
753    //set old security back
754    VirtualProtectEx(processhandle,pointer(a),codelength,original,a);  //ignore a
755
756    FlushInstructionCache(processhandle,pointer(a),codelength);
757
758    code[index].changed:=true;
759  end;
760  codelist2.Repaint;
761end;
762
763procedure TAdvancedOptions.Timer1Timer(Sender: TObject);
764begin
765  if red then
766  begin
767    mainform.ProcessLabel.Font.Color:=clred;
768    red:=false;
769  end
770  else
771  begin
772    mainform.ProcessLabel.Font.Color:=clGreen;
773    reD:=true;
774  end;
775end;
776
777procedure TAdvancedOptions.Button4Click(Sender: TObject);
778var i:integer;
779    fname,expectedFilename: string;
780    oldtitle: string;
781resourcestring StrSelectExeFor3D='Select the executable of the Direct-3D game';
782begin
783  {$ifndef net}
784  oldtitle:=opendialog1.Title;
785  opendialog1.Title:=StrSelectExeFor3D;
786
787  if Opendialog1.Execute then
788  begin
789    hyperscanview.HookDirect3d:=true;
790    hyperscanview.asktocontinue:=true;
791
792    KeysFileMapping:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,sizeof(tkeys),'CEKEYS');
793    if KeysFileMapping=0 then
794      raise exception.Create('Error while trying to create the shared key structure! (Which efficiently renders this whole feature useless)');
795
796    keys:=MapViewOfFile(KeysFileMapping,FILE_MAP_ALL_ACCESS,0,0,0);
797    if keys=nil then
798    begin
799      closehandle(KeysFileMapping);
800      raise exception.Create('Cheat Engine failed to get into the config of the selected program.');
801    end;
802
803    keys.configured:=false;
804
805
806    HyperscanView.HookDirect3d:=true;
807    HyperscanView.HookOpenGL:=false;
808
809
810    unpause;
811    detachIfPossible;
812    if Uppercase(extractfileext(opendialog1.FileName))<>'.EXE' then raise Exception.Create('You can only load EXE files');
813
814    Debuggerthread:=TDebugger.MyCreate(opendialog1.FileName);
815
816    while (debuggerthread<>nil) and (debuggerthread.attaching) do sleep(1);
817
818    mainForm.ProcessLabel.caption:=IntToHex(processid,8)+'-'+ExtractFileName(opendialog1.FileName);
819
820
821    mainform.debugproc:=true;
822
823    if formsettings.cbBreakOnAttach.checked then
824      memorybrowser.show;
825
826    mainform.enablegui(false);
827
828    with TFrmDirectx.Create(self) do show;
829  end;
830
831  opendialog1.title:=oldtitle;
832  {$endif}
833end;
834
835procedure TAdvancedOptions.FormCreate(Sender: TObject);
836begin
837  {$ifdef net}
838  button4.Visible:=false;
839  savebutton.Visible:=false;
840  pausebutton.Left:=savebutton.Left;
841  {$endif}
842end;
843
844procedure TAdvancedOptions.Button2Click(Sender: TObject);
845var i:integer;
846    fname,expectedFilename: string;
847    oldtitle: string;
848resourcestring StrSelectExeForOpenGL3D='Select the executable of the OpenGL game';
849begin
850  {$ifndef net}
851  oldtitle:=opendialog1.Title;
852  opendialog1.Title:=StrSelectExeForOpenGL3D;
853
854  if Opendialog1.Execute then
855  begin
856    hyperscanview.HookDirect3d:=true;
857    hyperscanview.asktocontinue:=true;
858
859    KeysFileMapping:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,sizeof(tkeys2),'CEKEYS2');
860    if KeysFileMapping=0 then
861      raise exception.Create('Error while trying to create the shared key structure! (Which efficiently renders this whole feature useless)');
862
863    keys2:=MapViewOfFile(KeysFileMapping,FILE_MAP_ALL_ACCESS,0,0,0);
864    if keys2=nil then
865    begin
866      closehandle(KeysFileMapping);
867      raise exception.Create('Cheat Engine failed to get into the config of the selected program.');
868    end;
869
870    keys2.configured:=false;
871
872    HyperscanView.HookDirect3d:=false;
873    HyperscanView.HookOpenGL:=true;
874
875    unpause;
876    detachIfPossible;
877    if Uppercase(extractfileext(opendialog1.FileName))<>'.EXE' then raise Exception.Create('You can only load EXE files');
878
879    Debuggerthread:=TDebugger.MyCreate(opendialog1.FileName);
880
881    while (debuggerthread<>nil) and (debuggerthread.attaching) do sleep(1);
882
883    mainForm.ProcessLabel.caption:=IntToHex(processid,8)+'-'+ExtractFileName(opendialog1.FileName);
884
885
886    mainform.debugproc:=true;
887
888    if formsettings.cbBreakOnAttach.checked then
889      memorybrowser.show;
890
891    mainform.enablegui(false);
892
893//    with TfrmOpenGL.Create(self) do show;
894  end;
895
896  opendialog1.title:=oldtitle;
897  {$endif}
898end;
899
900procedure TAdvancedOptions.Panel1Resize(Sender: TObject);
901begin
902  button1.Left:=panel1.Width div 2 - button1.width div 2;
903end;
904
905procedure TAdvancedOptions.Codelist2DblClick(Sender: TObject);
906var mi: TModuleInfo;
907begin
908  if codelist2.itemindex<>-1 then
909  begin
910    if code[codelist2.itemindex].modulename<>'' then
911    begin
912      symhandler.getmodulebyname(code[codelist2.itemindex].modulename,mi);
913      code[codelist2.itemindex].Address:=mi.baseaddress+code[codelist2.itemindex].offset;
914    end;
915
916    memorybrowser.disassemblerview.SelectedAddress:=code[codelist2.itemindex].Address;
917
918    if memorybrowser.Height<(memorybrowser.Panel1.Height+100) then memorybrowser.height:=memorybrowser.Panel1.Height+100;
919    memorybrowser.panel1.visible:=true;
920    memorybrowser.show;
921  end;
922end;
923
924procedure TAdvancedOptions.Panel2Resize(Sender: TObject);
925begin
926  label1.left:=(panel2.Width div 2)-(label1.Width div 2);
927end;
928
929procedure TAdvancedOptions.Codelist2CustomDrawItem(Sender: TCustomListView;
930  Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
931begin
932  if code[item.index].changed then sender.Canvas.Font.Color:=clred;
933end;
934
935end.
Note: See TracBrowser for help on using the browser.