root/Cheat Engine/CEFuncProc.pas @ 305

Revision 305, 85.9 kB (checked in by dark_byte, 8 months ago)

added support for xmm registers (untested)

Line 
1unit CEFuncProc;
2//This version of CEFuncProc has been COPIED to the server dir
3//Cheat Engine regular WONT look at this
4
5interface
6
7uses Windows,StdCtrls,Classes,SysUtils,dialogs,tlhelp32,forms,messages,
8Graphics,
9ComCtrls,
10reinit,
11assemblerunit,
12imagehlp,
13registry,
14
15{$ifdef netclient}
16netapis,
17{$else}
18NewKernelHandler,
19{$ifndef standalonetrainer}
20{$ifndef netserver}
21hypermode,
22firstscanhandler,
23{$endif}
24{$endif}
25{$endif}
26math,syncobjs, shellapi, ProcessHandlerUnit;
27
28//memscan
29type TScanOption=(soUnknownValue,soExactValue,soValueBetween,soBiggerThan,soSmallerThan, soIncreasedValue, soIncreasedValueBy, soDecreasedValue, soDecreasedValueBy, soChanged, soUnchanged, soSameAsFirst, soCustom);
30type TScanType=(stNewScan, stFirstScan, stNextScan);
31type TRoundingType=(rtRounded,rtExtremerounded,rtTruncated);
32type TVariableType=(vtByte, vtWord, vtDword, vtQword, vtSingle, vtDouble, vtString, vtUnicodeString, vtByteArray, vtBinary, vtAll, vtCustom, vtPointer);
33type TCustomScanType=(cstNone, cstAutoAssembler, cstCPP, cstDLLFunction);
34
35
36type PUINT64 = ^uint64;
37Type TBytes = array of integer; //An array that represents a row of byte. Ints are used to be able to represent wildcards (-1)
38type tfloatscan=(rounded,extremerounded,truncated);
39Type TMemoryRegion = record
40  BaseAddress: Dword;
41  MemorySize: Dword;
42  IsChild: boolean;  //means there is a region before it
43  startaddress: pointer; //pointer to a spot in the whole memory copy, it means the start of this region
44  end;
45type TMemoryRegions = array of TMemoryRegion;
46type PMemoryRegions = ^TMemoryRegions;
47
48type TBitAddress = record
49  address: dword;
50  bit: dword;
51end;
52
53type TBitAddressArray=array [0..0] of TBitAddress;
54type PBitAddressArray=^TBitAddressArray;
55
56type TProcessListInfo=record
57  processID: dword;
58  processIcon: HICON;
59end;
60PProcessListInfo=^TProcessListInfo;
61
62type TFreememoryThread = class(tthread)
63  public
64    Bitscan: array of byte;
65    tempbits: array of byte;
66    FoundAddress: array of dword;
67    FoundValue1:Array of Byte;
68    FoundValue2:Array of word;
69    FoundValue3:Array of Dword;
70    FoundValue7:Array of Int64;
71    FoundValue8:array of byte;
72    FoundValue4:Array of Single;
73    FoundValue5:Array of Double;
74    foundValue6:Array of int64;  //byte ?????
75    FoundValue1switch:Array of Byte;
76    FoundValue2switch:Array of word;
77    FoundValue3switch:Array of Dword;
78    FoundValue7switch:Array of Int64;
79    FoundValue8switch:array of byte;
80    FoundValue4switch:Array of Single;
81    FoundValue5switch:Array of Double;
82    foundValue6switch:Array of int64;
83
84    foundaddressB: array of TBitAddress;
85    previousmemory: array of byte;
86
87    SearchAddress: array of dword;
88    SearchAddressB: array of TBitAddress;
89
90    previousmemory1: array of Byte;
91    previousmemory2: array of word;
92    previousmemory3: array of dword;
93    previousmemory4: array of Single;
94    previousmemory5: array of Double;
95    previousmemory6: array of int64; //Byte;
96    PreviousMemory7: Array of Int64;
97    PreviousMemory8: array of byte;
98    previousmemory1switch: array of Byte;
99    previousmemory2switch: array of word;
100    previousmemory3switch: array of dword;
101    previousmemory4switch: array of Single;
102    previousmemory5switch: array of Double;
103    previousmemory6switch: array of int64; //Byte;
104    PreviousMemory7switch: Array of Int64;
105    PreviousMemory8switch: array of byte;
106   
107    Memory: ^Byte;
108    memory2: ^byte;
109    bytes: array of integer;  //-1=wildcard
110    bytearray: array of byte;
111
112    procedure execute; override;
113end;
114
115
116
117function ConvertHexStrToRealStr(const s: string): string;
118function HexStrToInt(const S: string): Integer;
119function HexStrToInt64(const S: string): Int64;
120
121function readAndParseAddress(address: dword; variableType: TVariableType): string;
122function isjumporcall(address: dword; var addresstojumpto: dword): boolean;
123{
124procedure quicksortmemoryregions(lo,hi: integer);     //obsolete
125}
126
127procedure rewritecode(processhandle: thandle; address:dword; buffer: pointer; size:dword);
128procedure rewritedata(processhandle: thandle; address:dword; buffer: pointer; size:dword);
129
130procedure GetProcessList(ProcessList: TListBox); overload;
131procedure GetProcessList(ProcessList: TStrings); overload;
132procedure GetWindowList(ProcessList: TListBox{; var ArrIcons: TBytes});
133function AvailMem:dword;
134function isreadable(address:dword):boolean;
135
136
137procedure RemoveAddress(address: Dword;bit: Byte; vartype: Integer);
138
139function GetCEdir:string;
140procedure Open_Process;
141Procedure Shutdown;
142function KeyToStr(key:word):string;
143
144function undolastscan(valtype: integer;hexadecimal:boolean): integer;
145
146procedure ConvertStringToBytes(scanvalue:string; hex:boolean;var bytes: TBytes);
147function getbit(bitnr: integer; bt: dword):integer;
148procedure setbit(bitnr: integer; var bt: Byte;state:integer); overload;
149procedure setbit(bitnr: integer; var bt: dword;state:integer); overload;
150
151function eflags_setCF(flagvalue: dword; value: integer): DWORD;
152function eflags_setPF(flagvalue: dword; value: integer): DWORD;
153function eflags_setAF(flagvalue: dword; value: integer): DWORD;
154function eflags_setZF(flagvalue: dword; value: integer): DWORD;
155function eflags_setSF(flagvalue: dword; value: integer): DWORD;
156function eflags_setTF(flagvalue: dword; value: integer): DWORD;
157function eflags_setIF(flagvalue: dword; value: integer): DWORD;
158function eflags_setDF(flagvalue: dword; value: integer): DWORD;
159function eflags_setOF(flagvalue: dword; value: integer): DWORD;
160function eflags_setIOPL(flagvalue: dword; value: integer): DWORD;
161function eflags_setNT(flagvalue: dword; value: integer): DWORD;
162function eflags_setRF(flagvalue: dword; value: integer): DWORD;
163function eflags_setVM(flagvalue: dword; value: integer): DWORD;
164function eflags_setAC(flagvalue: dword; value: integer): DWORD;
165function eflags_setVIF(flagvalue: dword; value: integer): DWORD;
166function eflags_setVIP(flagvalue: dword; value: integer): DWORD;
167function eflags_setID(flagvalue: dword; value: integer): DWORD;
168
169
170
171
172function ByteStringToText(s: string;hex: boolean):string;
173function ByteStringToDouble(s: string;hex: boolean):double;
174function ByteStringToSingle(s: string;hex: boolean):single;
175function ByteStringToInt(s: string;hex: boolean):int64;
176function VarToBytes(v: pointer; size: integer): string;
177function RawToString(const buf: array of byte; vartype: integer;showashex: boolean; bufsize: integer):string;
178function IntToBin(i: int64):string;
179function BinToInt(s: string): int64;
180
181procedure decimal(var key: char);
182procedure hexadecimal(var key: char);
183
184function GetSystemType: Integer;
185
186
187procedure ToggleOtherWindows;
188
189Procedure InjectDll(dllname: string; functiontocall: string='');
190Function GetRelativeFilePath(filename: string):string;
191
192function GetCPUCount: integer;
193function HasHyperthreading: boolean;
194procedure SaveFormPosition(form: Tform; extra: array of integer);
195function LoadFormPosition(form: Tform; var x: array of integer):boolean;
196
197function heapflagstostring(heapflags: dword): string;
198function allocationtypetostring(alloctype: dword): string;
199function allocationprotecttostring(protect: dword): string;
200function freetypetostring(freetype: dword):string;
201function isAddress(address: dword):boolean;
202
203{$ifndef standalonetrainer}
204Procedure CreateCodeCave(address:dword; sourceaddress:dword; sizeofcave: integer);
205{$endif}
206
207procedure errorbeep;
208
209
210
211{$ifndef net}
212procedure SetLanguage;
213
214{$endif}
215
216{$ifndef standalonetrainer}
217procedure DetachIfPossible;
218{$endif}
219
220procedure getexecutablememoryregionsfromregion(start: dword; stop:dword; var memoryregions: TMemoryRegions);
221
222const
223  Exact_value = 0;
224  Increased_value = 1;
225  Increased_value_by = 2;
226  Decreased_value = 3;
227  Decreased_value_by = 4;
228  Changed_value = 5;
229  Unchanged_value = 6;
230  Advanced_Scan = 7;
231  String_Scan = 8;
232  SmallerThan = 9;
233  BiggerThan = 10;
234  Userdefined = 11; //not used
235  ValueBetween = 12;
236  SameAsFirst = 13;
237
238  splitvalue=400000;
239  number=600;      //is my using the new value on my system arround 580000
240
241  WM_HOTKEY2=WM_USER+$800;
242
243type
244  MemoryRecordcet3 = record
245        Description : string[50];
246        Address : dword;
247        VarType : byte;
248        Bit     : Byte;
249        Frozen : boolean;
250        FrozenValue : Int64;
251        Group:  Byte;
252  end;
253
254type TCEPointer=record
255  Address: Dword;  //only used when last pointer in list
256  Interpretableaddress: string; //same as address
257  offset: integer;
258end;
259
260type TCEAlloc=record
261  address: dword;
262  varname: string;
263  size: dword;
264end;
265type PCEAlloc=^TCEAlloc;
266type TCEAllocArray=array of TCEAlloc;
267
268type
269  MemoryRecord = record
270        Description : string;
271        Address : dword;
272        interpretableaddress: string;
273        VarType : byte;
274        unicode : boolean;
275        IsPointer: Boolean;
276        pointers: array of TCEPointer;
277        Bit     : Byte;
278        bitlength: integer;
279        Frozen : boolean;
280        FrozenValue : Int64;
281        OldValue: string;   //not saved
282        Frozendirection: integer; //0=always freeze,1=only freeze when going up,2=only freeze when going down
283        Group:  Byte;
284        ShowAsHex: boolean;
285        autoassemblescript: string;
286        allocs: TCEAllocArray;
287  end;
288
289type
290  MemoryRecordOld = record
291        Description : string[50];
292        Address : dword;
293        VarType : byte;
294        Frozen : boolean;
295        FrozenValue : Dword;
296  end;
297
298type TDwordArray=array[0..100] of dword;
299type PDwordArray=^TDwordArray;
300
301type TSingleArray=array[0..100] of single;
302type PSingleArray=^TSingleArray;
303
304type TdoubleArray=array[0..100] of double;
305type PdoubleArray=^TdoubleArray;
306
307type Tint64Array=array[0..100] of int64;
308type Pint64Array=^Tint64Array;
309
310type Tuint64Array=array[0..100] of uint64;
311type Puint64Array=^Tuint64Array;
312
313
314
315type TScanSettings = record
316  UseHyperscan: boolean;
317  scanning: boolean;
318  CEProcessID: dword;
319  CEMainThreadID: Dword;
320  applicantionhandle: thandle;
321  mainformHandle: THandle;
322  formscanningHandle: THandle;
323  hyperscanwindow: Thandle;
324  StartAddress: Dword;
325  StopAddress: Dword;
326  Scantype: Integer;
327  ValueType: Integer;
328  roundingtype: tfloatscan;
329  scan:byte;
330  readonly: boolean;
331  FastScan: boolean;
332  Hexadecimal: boolean;
333  unicode: boolean;
334  percentage: boolean;
335  LowMemoryUsage: boolean;
336  Skip_PAGE_NOCACHE:boolean;
337  scan_mem_private:boolean;
338  scan_mem_image:boolean;
339  scan_mem_mapped: boolean;
340  scanvalue: string[255];
341  scanvalue2: string[255];
342  CheatEngineDir: string[255];
343  buffersize:dword;
344  priority:integer;
345  nrofbits:integer;
346  bitstring: string[255];
347  bitoffsetchange: integer;
348  asktocontinue: boolean;
349  HookDirect3d: boolean;
350  HookOpenGL:   boolean;
351  PacketEditor: boolean;
352  Stealthed: boolean;
353  hooknewprocesses: boolean;
354end;
355
356type tspeedhackspeed=record
357  speed: single;
358  sleeptime: dword;
359end;
360
361type TKeyCombo=array [0..4] of word;
362type TKeys=record
363  configured: boolean;
364  CEDir: string[255];
365  cewindow: thandle;
366
367  callibrationmode: boolean;  //false=no textureselect hud
368  callibrationkey: TKeycombo;
369
370  setcallibration: boolean;
371  mousecallibrationhorizontal1point: single;
372  mousecallibrationvertical1point: single;
373
374  mousecallibrationhorizontal2point: single;
375  mousecallibrationvertical2point: single;
376
377  mousecallibrationhorizontal5point: single;
378  mousecallibrationvertical5point: single;
379
380  mousecallibrationhorizontal10point: single;
381  mousecallibrationvertical10point: single;
382
383  mousecallibrationhorizontal20point: single;
384  mousecallibrationvertical20point: single;
385
386  mousecallibrationhorizontal40point: single;
387  mousecallibrationvertical40point: single;
388
389  loadaimsettingsfile: tkeycombo;
390  saveaimsettingsfile: tkeycombo;
391  aimsettings1: string[255];
392  Aimsettings2: string[255];
393  Aimsettings3: string[255];
394
395  setaimsetting1: tkeycombo;
396  setaimsetting2: tkeycombo;
397  setaimsetting3: tkeycombo;
398
399  nexttexture: tkeycombo;
400  previoustexture: tkeycombo;
401  locktexture: tkeycombo;
402
403  IncreaseX: tkeycombo;
404  DecreaseX: TKeyCombo;
405  Increasey: tkeycombo;
406  Decreasey: TKeyCombo;
407  Increasez: tkeycombo;
408  Decreasez: TKeyCombo;
409
410  HoldAutoaimtoggle: boolean;
411  autoshoot: boolean;
412  autoaimtoggle: tKeycombo;
413  increaselag: tkeycombo;
414  decreaselag: tkeycombo;
415
416  zoomin,zoomout: TKeyCombo;
417  nozoom: tKeyCombo;
418  zoom1: tKeyCombo;
419  zoomlevel1: single;
420  zoom2: tkeycombo;
421  zoomlevel2: single;
422  zoom3: tkeycombo;
423  zoomlevel3: single;
424  zoom4: tkeycombo;
425  zoomlevel4: single;
426  zoom5: tkeycombo;
427  zoomlevel5: single;
428
429  zoomdelta: single;
430  lagdelta: integer;
431
432  setlag: boolean;
433  lagtoset: dword;
434  usefpslag: boolean;
435
436  rotateleft: tKeycombo;
437  rotateright: tkeycombo;
438  rotateup: tkeycombo;
439  rotatedown: tkeycombo;
440  moveleft: tkeycombo;
441  moveright: tkeycombo;
442  moveup: tkeycombo;
443  movedown: tkeycombo;
444  moveforward: tkeycombo;
445  movebackwards: tkeycombo;
446
447  movespeed: single;
448  rotatespeed: single;
449
450  setcameraback: tkeycombo;
451
452  zbuffer: tkeycombo;
453  fog: tkeycombo;
454  lighting: tkeycombo;
455  wireframe: tkeycombo;
456
457  ShowKeylist: tkeycombo;
458
459  SaveAlltextures: TKeycombo;
460
461  selectedlagrecord: string[50];
462  lagmemorytype: byte;
463  getlagfrommemory: boolean;
464  nrofoffsets: dword;
465  lagaddress: dword;
466  offset1: dword;
467  offset2: dword;
468  offset3: dword;
469  offset4: dword;
470  offset5: dword;
471  offset6: dword;
472  offset7: dword;
473  offset8: dword;
474  offset9: dword;
475  offset10: dword;
476  offset11: dword;
477  offset12: dword;
478  offset13: dword;
479  offset14: dword;
480  offset15: dword;
481
482
483  pollinginterval: integer;
484end;
485type PKeys= ^TKeys;
486
487type TKeys2=record
488  configured: boolean;
489  CEDir: string[255];
490  cewindow: thandle;
491
492  textures: tkeycombo;
493  lighting: tkeycombo;
494  depthtest: tkeycombo;
495  fog: tkeycombo;
496
497
498  zoomin,zoomout: TKeyCombo;
499  nozoom: tKeyCombo;
500  zoom1: tKeyCombo;
501  zoomlevel1: single;
502  zoom2: tkeycombo;
503  zoomlevel2: single;
504  zoom3: tkeycombo;
505  zoomlevel3: single;
506  zoom4: tkeycombo;
507  zoomlevel4: single;
508  zoom5: tkeycombo;
509  zoomlevel5: single;
510
511  zoomdelta: single;
512
513
514  pollinginterval: integer;
515end;
516type PKeys2= ^TKeys2;
517
518
519
520function ConvertKeyComboToString(x: tkeycombo):string;
521
522{
523ProcessID and ProcessHandle as functions untill all code has been converted to
524make use of ProcessHandlerUnit
525}
526function ProcessID: dword;
527function ProcessHandle: THandle;
528
529//Global vars:
530var
531  old8087CW: word;  //you never know...
532  ProcessSelected: Boolean;
533  //ProcessID: Dword; //deperecated
534  //ProcessHandle: Thandle;
535
536  Skip_PAGE_NOCACHE: boolean;
537  Scan_MEM_PRIVATE: boolean;
538  Scan_MEM_IMAGE: boolean;
539  Scan_MEM_MAPPED: boolean;
540
541  CheatEngineDir: String;
542  WindowsDir: string;
543  GetProcessIcons: Boolean;
544  ProcessesWithIconsOnly: boolean;
545
546//scanhelpers
547  nrofbits: integer;
548  Bitscan: array of byte;
549  tempbits: array of byte;
550
551  bitoffsetchange: integer;
552
553  FoundValue1:Array of Byte;
554  FoundValue1switch:Array of Byte;
555
556  FoundValue2:Array of word;
557  FoundValue2switch:Array of word;
558
559  FoundValue3:Array of Dword;
560  FoundValue3switch:Array of Dword;
561
562  FoundValue4:Array of Single;
563  FoundValue4switch:Array of Single;
564
565  FoundValue5:Array of Double;
566  FoundValue5switch:Array of Double;
567
568  foundValue6:Array of int64;
569  foundValue6switch:Array of int64;
570
571  FoundValue7:Array of Int64;
572  FoundValue7switch:Array of Int64;
573
574  FoundValue8:array of byte;
575  FoundValue8switch:array of byte;
576
577  FoundAddress: array of dword;
578  FoundAddressSwitch: array of dword;
579
580  foundaddressB: array of TBitAddress;
581  foundaddressBswitch: array of TBitAddress; 
582
583
584  tempbytearray: array of byte;
585  tempwordarray: array of word;
586  tempdwordarray: array of dword;
587  tempsinglearray: array of single;
588  tempdoublearray: array of double;
589  tempint64array: array of int64;
590
591
592//--------
593  previousmemory: array of byte;
594
595  SearchAddress: array of dword;
596  searchaddressswitch: array of dword;
597
598  SearchAddressB: array of TBitAddress;
599
600  previousmemory1,previousmemory1switch: array of Byte;
601  previousmemory2,previousmemory2switch: array of word;
602  previousmemory3,previousmemory3switch: array of dword;
603  previousmemory4,previousmemory4switch: array of Single;
604  previousmemory5,previousmemory5switch: array of Double;
605  previousmemory6,previousmemory6switch: array of int64; //Byte;
606  PreviousMemory7,previousmemory7switch: Array of Int64;
607  PreviousMemory8,previousmemory8switch: array of byte;
608
609//---------
610  helpstr,helpstr2: string;
611  bytes: array of integer;  //-1=wildcard
612  bytearray: array of byte;
613
614
615
616//  MemoryRegion: array of TMemoryRegion;
617//  MemoryRegions: Integer;
618 
619//  Memory: Array of Byte;
620  Memory: ^Byte;
621  memory2: ^byte;
622
623
624  advanced: boolean;
625  //global files, so when an exception happens I can close them
626  addressfile, memoryfile: File;
627  newAddressfile,newmemoryfile: File;
628
629  buffersize: dword;
630  overridedebug: boolean;
631
632  totalbytes: dword;
633  currentbyte: dword;
634
635
636  //hide/show windows
637  windowlist: array of thandle;
638  lastforeground,lastactive: thandle;
639  donthidelist: array of string;
640  onlyfront: boolean;
641  allwindowsareback:boolean;
642
643  HyperscanFileMapping: THandle;
644  HyperscanView: ^TScanSettings;
645 
646  hookedin:boolean;
647  keys: PKeys;
648  keys2: PKeys2;
649  keysfilemapping: THandle;
650
651  //stealth globals
652  le: dword;
653  ownprocesshandle: THandle;
654  stealthhook: thandle;
655
656  //windows version data
657  iswin2kplus: boolean;
658  scanpriority: TThreadPriority;
659
660  {$ifndef standalonetrainer}
661  {$ifndef net}
662  hypermode: thypermode;
663  useAPCtoInjectDLL: boolean;
664  {$endif}
665  {$endif}
666
667  tempdir: pchar;
668
669
670  processhandler: TProcessHandler;
671
672implementation
673
674{$ifdef net}
675uses disassembler,debugger;
676{$endif}
677
678{$ifndef net}
679
680{$ifndef standalonetrainer}
681uses disassembler,debugger,symbolhandler,frmProcessWatcherUnit,kerneldebugger;
682{$else}
683uses symbolhandler;
684{$endif}
685
686{$endif}
687
688function ProcessID: dword;
689begin
690  result:=ProcessHandler.Processid;
691end;
692
693function ProcessHandle: THandle;
694begin
695  result:=ProcessHandler.ProcessHandle;
696end;
697
698
699procedure TFreememorythread.execute;
700begin
701  setlength(bitscan,0);
702  setlength(tempbits,0);
703  setlength(FoundAddress,0);
704
705  setlength(FoundValue1,0);
706  setlength(FoundValue2,0);
707  setlength(FoundValue3,0);
708  setlength(FoundValue4,0);
709  setlength(FoundValue5,0);
710  setlength(foundValue6,0);
711  setlength(FoundValue7,0);
712  setlength(FoundValue8,0);
713  setlength(FoundValue1switch,0);
714  setlength(FoundValue2switch,0);
715  setlength(FoundValue3switch,0);
716  setlength(FoundValue4switch,0);
717  setlength(FoundValue5switch,0);
718  setlength(foundValue6switch,0);
719  setlength(FoundValue7switch,0);
720  setlength(FoundValue8switch,0);
721
722
723    //floating point notations
724
725
726  setlength(foundaddressB,0);
727
728  setlength(previousmemory,0);
729
730  setlength(SearchAddress,0);
731  setlength(SearchAddressB,0);
732
733  setlength(previousmemory1,0);
734  setlength(previousmemory2,0);
735  setlength(previousmemory3,0);
736  setlength(previousmemory4,0);
737  setlength(previousmemory5,0);
738  setlength(previousmemory6,0);
739  setlength(PreviousMemory7,0);
740  setlength(PreviousMemory8,0);
741
742  setlength(previousmemory1switch,0);
743  setlength(previousmemory2switch,0);
744  setlength(previousmemory3switch,0);
745  setlength(previousmemory4switch,0);
746  setlength(previousmemory5switch,0);
747  setlength(previousmemory6switch,0);
748  setlength(PreviousMemory7switch,0);
749  setlength(PreviousMemory8switch,0);
750
751  if not advanced then     //if the lastscan was a advanced, better not whipe the memory (yet!)
752  begin
753    if memory<>nil then freemem(memory);
754    memory:=nil;
755
756    if memory2<>nil then freemem(memory2);
757    memory2:=nil;
758  end;
759
760  setlength(bytes,0);
761  setlength(bytearray,0);
762end;
763
764type TSaveDataThread=class(tthread)
765  public
766    buffer1: pointer;
767    buffer2: pointer;
768    buffersize1: dword;
769    buffersize2: dword;
770    file1: ^file;
771    file2: ^file;
772    datawritten: tevent;
773    dataavailable:tevent;
774
775    procedure execute; override;
776    constructor create(suspended:boolean);
777    destructor destroy; override;
778end;
779
780procedure TSaveDataThread.execute;
781var ignore: dword;
782begin
783  dataavailable.WaitFor(infinite);
784  while not terminated do
785  begin
786    blockwrite(file1^,buffer1^,buffersize1,ignore);
787    blockwrite(file2^,buffer2^,buffersize2,ignore);
788
789    datawritten.SetEvent; //tell the others that you're ready to write again
790    dataavailable.WaitFor(infinite); //wait for the 'ready to write' event
791  end;
792end;
793
794destructor TSaveDataThread.destroy;
795begin
796  datawritten.Free;
797  dataavailable.free;
798  inherited destroy;
799end;
800
801constructor TSaveDataThread.create(suspended:boolean);
802begin
803  datawritten:=tevent.Create(nil,false,true,'');
804  dataavailable:=tevent.create(nil,false,false,'');
805
806  inherited create(suspended);
807end;
808
809var FlushThread:TSaveDataThread;
810
811procedure flushbuffer(var file1, file2:file; buffer1:pointer; buffer1size:integer; buffer2:pointer; buffer2size:integer);
812begin
813  flushthread.datawritten.ResetEvent;
814 
815  flushthread.file1:=@file1;
816  flushthread.file2:=@file2;
817  flushthread.buffer1:=buffer1;
818  flushthread.buffer2:=buffer2;
819  flushthread.buffersize1:=buffer1size;
820  flushthread.buffersize2:=buffer2size;
821  flushthread.dataavailable.SetEvent;
822end;
823
824procedure finishflushing;
825begin
826  flushthread.datawritten.WaitFor(infinite);
827  flushthread.datawritten.SetEvent;
828end;
829
830//------------------------------------
831
832type TPrefetchDataThread=class(tthread)
833  public
834    buffer1: pointer;
835    buffer2: pointer;
836    buffersize1: dword;
837    buffersize2: dword;
838    file1: ^file;
839    file2: ^file;
840    dataread: tevent;
841    startreading:tevent;
842
843    actualread: dword;
844
845    procedure execute; override;
846    constructor create(suspended:boolean);
847    destructor destroy; override;
848end;
849
850procedure TPrefetchDataThread.execute;
851var ignore,tmp: dword;
852begin
853  startreading.WaitFor(infinite);
854
855  while not terminated do
856  begin
857    self.actualread:=0;
858    blockread(file1^,buffer1^,buffersize1,tmp);
859    blockread(file2^,buffer2^,buffersize2,ignore);
860
861    self.actualread:=tmp;
862
863    dataread.SetEvent; //tell the others that you're ready to read again
864    startreading.WaitFor(infinite);
865  end;
866end;
867
868destructor TPrefetchDataThread.destroy;
869begin
870  dataread.Free;
871  startreading.free;
872  inherited destroy;
873end;
874
875constructor TPrefetchDataThread.create(suspended:boolean);
876begin
877  dataread:=tevent.Create(nil,false,true,'');
878  startreading:=tevent.create(nil,false,false,'');
879
880  inherited create(suspended);
881end;
882
883var PrefetchThread:TPrefetchDataThread;
884
885procedure prefetchbuffer(var file1, file2:file; buffer1:pointer; buffer1size:integer; buffer2:pointer; buffer2size:integer);
886begin
887  PrefetchThread.dataread.ResetEvent;
888
889  PrefetchThread.file1:=@file1;
890  PrefetchThread.file2:=@file2;
891  PrefetchThread.buffer1:=buffer1;
892  PrefetchThread.buffer2:=buffer2;
893  PrefetchThread.buffersize1:=buffer1size;
894  PrefetchThread.buffersize2:=buffer2size;
895  PrefetchThread.startreading.SetEvent;
896end;
897
898function finishprefetching:dword;
899begin
900  PrefetchThread.dataread.WaitFor(infinite);//wait for the datread event to be set
901  result:=prefetchthread.actualread;
902end;
903
904procedure errorbeep;
905begin
906  beep;
907  sleep(100);
908  beep;
909  sleep(100);
910  beep;
911  sleep(100);
912end;
913
914function isreadable(address:dword):boolean;
915var mbi: _MEMORY_BASIC_INFORMATION;
916begin
917  VirtualQueryEx(processhandle,pointer(address),mbi,sizeof(mbi));
918  result:=mbi.State=mem_commit;
919end;
920
921function RawToString(const buf: array of byte; vartype: integer;showashex: boolean; bufsize: integer):string;
922var x: pchar;
923    i: integer;
924begin
925  //buffsize has to match the type else error
926  if bufsize=0 then
927  begin
928    result:='???';
929    exit;
930  end;
931
932  try
933  case vartype of
934    0: if bufsize<>1 then result:='???' else if showashex then result:=inttohex(buf[0],2) else result:=inttostr(buf[0]);
935    1: if bufsize<>2 then result:='???' else if showashex then result:=inttohex(pshortint(@buf[0])^,2) else result:=inttostr(pshortint(@buf[0])^);
936    2: if bufsize<>4 then result:='???' else if showashex then result:=inttohex(pint(@buf[0])^,4) else result:=inttostr(pint(@buf[0])^);
937    3: if bufsize<>4 then result:='???' else result:=floattostr(psingle(@buf[0])^);
938    4: if bufsize<>8 then result:='???' else result:=floattostr(pdouble(@buf[0])^);
939    6: if bufsize<>4 then result:='???' else if showashex then result:=inttohex(pint64(@buf[0])^,8) else result:=inttostr(pint64(@buf[0])^);
940    7:
941    begin
942      getmem(x,bufsize+1);
943      x[bufsize]:=#0;
944      result:=x;
945      freemem(x);
946    end;
947
948    8: //array of bytes
949    begin
950      result:='';
951      for i:=0 to bufsize-1 do
952        result:=result+'-'+inttohex(buf[bufsize],2);
953    end;
954
955    else result:='not supported in this version';
956  end;
957  except
958    result:='Not convertable';
959  end;
960end;
961
962function ConvertKeyComboToString(x: tkeycombo):string;
963var i: integer;
964    newstr: string;
965begin
966  result:='';
967  for i:=0 to 4 do
968    if x[i]=0 then
969      break
970    else
971    begin
972      newstr:='';
973      case x[i] of
974        vk_lbutton: newstr:='Left MB';
975        vk_mbutton: newstr:='Middle MB';
976        vk_rbutton: newstr:='Right MB';
977        VK_BACK : newstr:='Backspace';
978        VK_SHIFT: newstr:='Shift';
979        VK_CONTROL: newstr:='Ctrl';
980        VK_MENU: newstr:='Alt';
981        VK_TAB  : newstr:='Tab';
982        VK_CLEAR        : newstr:='Clear';
983        VK_RETURN       : newstr:='Enter';
984        VK_PAUSE        : newstr:='Pause';
985        VK_CAPITAL      : newstr:='Caps Lock';
986        VK_ESCAPE       : newstr:='Esc';
987        VK_SPACE        : newstr:='Space bar';
988        VK_PRIOR        : newstr:='Page Up';
989        VK_NEXT : newstr:='Page Down';
990        VK_END  : newstr:='End';
991        VK_HOME : newstr:='Home';
992        VK_LEFT : newstr:='Left Arrow';
993        VK_UP   : newstr:='Up Arrow';
994        VK_RIGHT        : newstr:='Right Arrow';
995        VK_DOWN : newstr:='Down Arrow';
996        VK_SELECT       : newstr:='Select';
997        VK_PRINT        : newstr:='Print';
998        VK_EXECUTE      : newstr:='Execute';
999        VK_SNAPSHOT     : newstr:='Print Screen';
1000        VK_INSERT       : newstr:='Insert';
1001        VK_DELETE       : newstr:='Delete';
1002        VK_HELP : newstr:='Help';
1003        VK_LWIN : newstr:='Left Windows key';
1004        VK_RWIN : newstr:='Right Windows key';
1005        VK_APPS : newstr:='Applications key';
1006        VK_NUMPAD0      : newstr:='numeric 0';
1007        VK_NUMPAD1      : newstr:='numeric 1';
1008        VK_NUMPAD2      : newstr:='numeric 2';
1009        VK_NUMPAD3      : newstr:='numeric 3';
1010        VK_NUMPAD4      : newstr:='numeric 4';
1011        VK_NUMPAD5      : newstr:='numeric 5';
1012        VK_NUMPAD6      : newstr:='numeric 6';
1013        VK_NUMPAD7      : newstr:='numeric 7';
1014        VK_NUMPAD8      : newstr:='numeric 8';
1015        VK_NUMPAD9      : newstr:='numeric 9';
1016        VK_MULTIPLY     : newstr:='numeric *';
1017        VK_ADD  : newstr:='numeric +';
1018        VK_SEPARATOR : newstr:='numeric Separator';
1019        VK_SUBTRACT     : newstr:='numeric -';
1020        VK_DECIMAL      : newstr:='numeric .';
1021        VK_DIVIDE       : newstr:='numeric /';
1022        VK_F1   : newstr:='F1';
1023        VK_F2   : newstr:='F2';
1024        VK_F3   : newstr:='F3';
1025        VK_F4   : newstr:='F4';
1026        VK_F5   : newstr:='F5';
1027        VK_F6   : newstr:='F6';
1028        VK_F7   : newstr:='F7';
1029        VK_F8   : newstr:='F8';
1030        VK_F9   : newstr:='F9';
1031        VK_F10  : newstr:='F10';
1032        VK_F11  : newstr:='F11';
1033        VK_F12  : newstr:='F12';
1034        VK_F13  : newstr:='F13';
1035        VK_F14  : newstr:='F14';
1036        VK_F15  : newstr:='F15';
1037        VK_F16  : newstr:='F16';
1038        VK_F17  : newstr:='F17';
1039        VK_F18  : newstr:='F18';
1040        VK_F19  : newstr:='F19';
1041        VK_F20  : newstr:='F20';
1042        VK_F21  : newstr:='F21';
1043        VK_F22  : newstr:='F22';
1044        VK_F23  : newstr:='F23';
1045        VK_F24  : newstr:='F24';
1046        VK_NUMLOCK      : newstr:='Num Lock';
1047        VK_SCROLL       : newstr:='Scroll Lock';
1048        48..57      : newstr:=chr(x[i]);
1049        65..90      : newstr:=chr(x[i]);
1050        else  newstr:='#'+inttostr(x[i]);
1051      end;
1052
1053      result:=result+newstr+'+';
1054    end;
1055
1056  result:=copy(result,1,length(result)-1);
1057end;
1058
1059procedure getexecutablememoryregionsfromregion(start: dword; stop:dword; var memoryregions: tmemoryregions);
1060var address: dword;
1061    mbi: memory_basic_information;
1062begin
1063  setlength(memoryregions,0);
1064  address:=start;
1065  while (address<stop) and (VirtualQueryEx(processhandle,pointer(address),mbi,sizeof(mbi))<>0) and ((address+mbi.RegionSize)>address) do
1066  begin
1067    if ((mbi.AllocationProtect and PAGE_EXECUTE)=PAGE_EXECUTE) or
1068       ((mbi.AllocationProtect and PAGE_EXECUTE_READ)=PAGE_EXECUTE_READ) or
1069       ((mbi.AllocationProtect and PAGE_EXECUTE_READWRITE)=PAGE_EXECUTE_READWRITE) or
1070       ((mbi.AllocationProtect and PAGE_EXECUTE_WRITECOPY)=PAGE_EXECUTE_WRITECOPY) then
1071    begin
1072      //executable
1073      setlength(memoryregions,length(memoryregions)+1);
1074      memoryregions[length(memoryregions)-1].BaseAddress:=dword(mbi.baseaddress);
1075      memoryregions[length(memoryregions)-1].MemorySize:=mbi.RegionSize;
1076    end;
1077
1078    inc(address,mbi.RegionSize);
1079  end;
1080
1081end;
1082
1083
1084{$ifndef standalonetrainer}
1085procedure FillMemoryProcess(start:dword;count:dword;fillvalue:byte);
1086var buf: array of byte;
1087    original,actualwritten:dword;
1088begin
1089  setlength(buf,count);
1090  try
1091    fillmemory(@buf[0],count,fillvalue);
1092    rewritedata(processhandle,start,@buf[0],count);
1093  finally
1094    setlength(buf,0);
1095  end;
1096end;
1097
1098
1099Procedure CreateCodeCave(address:dword; sourceaddress:dword; sizeofcave: integer);
1100var x,y: dword;
1101    i:integer;
1102    ignore,temp: string;
1103    replacedopcodes: array of string;
1104    jumpback: array [0..4] of byte;
1105    reassembledinstruction:tassemblerbytes;
1106
1107    overwritesize: dword;
1108begin
1109  x:=sourceaddress;
1110
1111  while x<(sourceaddress+5) do
1112  begin
1113    setlength(replacedopcodes,length(replacedopcodes)+1);
1114    temp:=disassemble(x,ignore);
1115    temp:=copy(temp,pos('-',temp)+1,length(temp));
1116    temp:=copy(temp,pos('-',temp)+2,length(temp));
1117
1118    replacedopcodes[length(replacedopcodes)-1]:=temp;
1119  end;
1120
1121  overwritesize:=x-sourceaddress;
1122
1123  x:=address+sizeofcave-5;
1124  y:=x;
1125
1126  jumpback[0]:=$e9;
1127  pdword(@jumpback[1])^:=sourceaddress-x;
1128
1129  virtualprotectex(processhandle,pointer(address),sizeofcave,PAGE_EXECUTE_READWRITE ,x);
1130  fillmemoryprocess(address,sizeofcave,$90);
1131
1132  if sizeofcave>5 then
1133    writeprocessmemory(processhandle,pointer(y),@jumpback[0],5,x);
1134
1135  x:=address;
1136  for i:=0 to length(replacedopcodes)-1 do
1137  begin
1138    assemble(replacedopcodes[i],x,reassembledinstruction);
1139    writeprocessmemory(processhandle,pointer(x),@reassembledinstruction[0],length(reassembledinstruction),y);
1140    inc(x,length(reassembledinstruction));
1141  end;
1142
1143  virtualprotectex(processhandle,pointer(sourceaddress),overwritesize,x,y);
1144
1145
1146  //now place the jmp
1147  setlength(reassembledinstruction,overwritesize);
1148  reassembledinstruction[0]:=$e9;
1149  pdword(@reassembledinstruction[1])^:=address-sourceaddress-5;
1150
1151  for i:=5 to overwritesize-1 do
1152    reassembledinstruction[i]:=$90;
1153
1154  RewriteData(processhandle,sourceaddress,@reassembledinstruction[0],overwritesize);
1155end;
1156{$endif}
1157
1158
1159
1160{$ifndef net}
1161procedure SetLanguage;
1162begin
1163  {$ifdef DEU}if LoadNewResourceModule(LANG_GERMAN) <> 0 then ReinitializeForms{$endif}
1164  {$ifdef RUS}if LoadNewResourceModule(LANG_RUSSIAN) <> 0 then ReinitializeForms{$endif}
1165  {$ifdef NLD}if LoadNewResourceModule(LANG_DUTCH) <> 0 then ReinitializeForms{$endif}
1166end;
1167{$endif}
1168
1169{$ifndef standalonetrainer}
1170{$ifndef net}
1171//Returns a random threadid owned by the target process
1172function getathreadid(processid:dword):dword;
1173var i: integer;
1174    ths: thandle;
1175    tE: threadentry32;
1176begin
1177  if frmProcessWatcher<>nil then
1178  begin
1179    //first find a processid using the processwatcher
1180
1181    frmProcessWatcher.processesMREW.BeginRead;
1182    try
1183      for i:=0 to length(frmProcessWatcher.processes)-1 do
1184        if frmProcessWatcher.processes[i].processid=processid then
1185        begin
1186          if length(frmProcessWatcher.processes[i].threadlist)>0 then
1187          begin
1188            result:=frmProcessWatcher.processes[i].threadlist[0].threadid;
1189            exit;
1190          end;
1191        end;
1192    finally
1193      frmProcessWatcher.processesMREW.EndRead;
1194    end;
1195
1196  end;
1197
1198  //no exit yet, so use a enumeration of all threads and this processid
1199  ths:=CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);
1200  if ths<>0 then
1201  begin
1202    te.dwSize:=sizeof(te);
1203    if Thread32First(ths,te) then
1204    begin
1205      repeat
1206        if te.th32OwnerProcessID=processid then
1207        begin
1208          result:=te.th32ThreadID;
1209          closehandle(ths);
1210          exit;
1211        end;
1212
1213
1214      until not thread32Next(ths,te);
1215    end;
1216  end;
1217
1218  closehandle(ths);
1219end;
1220{$endif}
1221
1222procedure DetachIfPossible;
1223var crashcounter: integer;
1224    waitform: TForm;
1225    msg: tlabel;
1226begin
1227  //detach the debugger
1228
1229  waitform:=nil;
1230  crashcounter:=0;
1231
1232  {$ifndef net}
1233  if debuggerthread=nil then
1234  begin
1235    if kdebugger.isactive then
1236      KDebugger.StopDebugger;
1237
1238    exit;
1239  end
1240  else debuggerthread.Terminate;
1241
1242  if @DebugActiveProcessStop=@DebugActiveProcessStopProstitute then //lets help it a hand if it cant detach gracefully
1243    terminateprocess(processhandle,0)
1244  else
1245  begin
1246    if debuggerthread<>nil then
1247    begin
1248      //show a window asking the user to wait and not to freak out and think CE crashed!
1249      waitform:=TForm.Create(nil);
1250      with waitform do
1251      begin
1252        waitform.Caption:='Detaching...';
1253        msg:=TLabel.Create(waitform);
1254        msg.Caption:='Please wait while Cheat Engine tries to detach from the current process(This wont take longer than 30 seconds)';
1255
1256        waitform.Width:=msg.Width+20;
1257        waitform.clientHeight:=50;
1258
1259        msg.Left:=7;
1260        msg.Top:=(waitform.ClientHeight div 2) - (msg.Height div 2);
1261        msg.Parent:=waitform;
1262
1263        //waitform.Parent:=self;
1264        waitform.BorderStyle:=bsDialog;
1265        waitform.BorderIcons:=[];
1266
1267        waitform.Position:=poScreenCenter;
1268        waitform.Show;
1269        waitform.Repaint;
1270      end;
1271    end;
1272  end;
1273
1274  while (debuggerthread<>nil) and (debuggerthread.attached) and (crashcounter<30) do
1275  begin
1276    inc(crashcounter);
1277    sleep(1000);
1278  end;
1279
1280  if crashcounter=30 then messagedlg('Detaching failed!!! Your process is lost!',mtError,[mbok],0);
1281
1282  if waitform<>nil then
1283  begin
1284    waitform.Hide;
1285    waitform.Free;
1286    waitform:=nil;
1287  end;
1288
1289
1290  {$endif}
1291
1292end;
1293{$endif}
1294
1295
1296Procedure InjectDll(dllname: string; functiontocall: string='');
1297var LoadLibraryPtr: pointer;
1298    GetProcAddressPtr: Pointer;
1299
1300
1301    h: Thandle;
1302
1303    inject: array [0..4095] of byte;
1304    x:dword;
1305
1306    outp:TAssemblerBytes;
1307    counter: integer;
1308    position,position2: dword;
1309
1310    dllLocation: string;
1311    startaddresS: dword;
1312    functionloc: dword;
1313    injectionlocation: pointer;
1314    threadhandle: thandle;
1315begin
1316  h:=LoadLibrary('Kernel32.dll');
1317  if h=0 then raise exception.Create('No kernel32.dll loaded');
1318
1319  injectionlocation:=nil;
1320  try
1321    try
1322      getprocaddressptr:=pointer(symhandler.getAddressFromName('GetProcAddress',true));
1323    except
1324      GetProcAddressPtr:=GetProcAddress(h,'GetProcAddress');
1325    end;
1326
1327    if getprocaddressptr=nil then raise exception.Create('GetProcAddress not found');
1328
1329    try
1330      LoadLibraryPtr:=pointer(symhandler.getAddressFromName('LoadLibraryA',true));
1331    except
1332      //failed getting the address of LoadLibraryA, use old method
1333      LoadLibraryPtr:=GetProcAddress(h,'LoadLibraryA');
1334    end;
1335
1336
1337    if LoadLibraryptr=nil then raise exception.Create('LoadLibraryA not found');
1338
1339    injectionlocation:=VirtualAllocEx(processhandle,nil,4096,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
1340
1341    if injectionlocation=nil then raise exception.Create('Failed to allocate memory');
1342
1343    dlllocation:=dllname;
1344
1345    position:=dword(injectionlocation);
1346    position2:=0;
1347    copymemory(@inject[0],pchar(dllLocation+#0),length(dllLocation)+1);
1348    inc(position,length(dllLocation)+1);
1349    inc(position2,length(dllLocation)+1);
1350
1351    functionloc:=position;
1352    copymemory(@inject[position2],pchar(functiontocall+#0),length(functiontocall)+1);
1353    inc(position,length(functiontocall)+1);
1354    inc(position2,length(functiontocall)+1);
1355    startaddress:=position;
1356
1357    //loadlibrary(cehook);
1358    assemble('PUSH '+IntToHex(dword(injectionlocation),8),position,outp);
1359    copymemory(@inject[position2],outp,length(outp));
1360    inc(position,length(outp));
1361    inc(position2,length(outp));
1362
1363    assemble('CALL '+IntToHex(dword(LoadLibraryPtr),8),position,outp);
1364    copymemory(@inject[position2],outp,length(outp));
1365    inc(position,length(outp));
1366    inc(position2,length(outp));
1367
1368
1369    //safetycode, test if the dll was actually loaded and skip if not
1370    assemble('TEST EAX,EAX',position,outp);
1371    copymemory(@inject[position2],outp,length(outp));
1372    inc(position,length(outp));
1373    inc(position2,length(outp));
1374
1375    assemble('JNE '+inttohex(position+3+5,8),position,outp); //jump over the ret
1376    copymemory(@inject[position2],outp,length(outp));
1377    inc(position,length(outp));
1378    inc(position2,length(outp));
1379
1380    assemble('MOV EAX,2',position,outp); //exitcode=2
1381    copymemory(@inject[position2],outp,length(outp));
1382    inc(position,length(outp));
1383    inc(position2,length(outp));
1384
1385    assemble('RET',position,outp);
1386    copymemory(@inject[position2],outp,length(outp));
1387    inc(position,length(outp));
1388    inc(position2,length(outp));
1389
1390
1391    if functiontocall<>'' then
1392    begin
1393      //getprocaddress
1394      assemble('PUSH '+IntToHex(functionloc,8),position,outp);
1395      copymemory(@inject[position2],outp,length(outp));
1396      inc(position,length(outp));
1397      inc(position2,length(outp));
1398
1399      assemble('PUSH EAX',position,outp);
1400      copymemory(@inject[position2],outp,length(outp));
1401      inc(position,length(outp));
1402      inc(position2,length(outp));
1403
1404      assemble('CALL '+IntToHex(dword(GetProcAddressPtr),8),position,outp);
1405      copymemory(@inject[position2],outp,length(outp));
1406      inc(position,length(outp));
1407      inc(position2,length(outp));
1408
1409      assemble('TEST EAX,EAX',position,outp);
1410      copymemory(@inject[position2],outp,length(outp));
1411      inc(position,length(outp));
1412      inc(position2,length(outp));
1413
1414      assemble('JNE '+inttohex(position+3+5,8),position,outp);
1415      copymemory(@inject[position2],outp,length(outp));
1416      inc(position,length(outp));
1417      inc(position2,length(outp));
1418
1419      assemble('MOV EAX,3',position,outp); //exitcode=3
1420      copymemory(@inject[position2],outp,length(outp));
1421      inc(position,length(outp));
1422      inc(position2,length(outp));
1423
1424      assemble('RET',position,outp);
1425      copymemory(@inject[position2],outp,length(outp));
1426      inc(position,length(outp));
1427      inc(position2,length(outp));
1428
1429      //call function
1430      assemble('CALL EAX',position,outp);
1431      copymemory(@inject[position2],outp,length(outp));
1432      inc(position,length(outp));
1433      inc(position2,length(outp));
1434    end;
1435
1436
1437    assemble('MOV EAX,1',position,outp); //causes the exitcode of the thread be 1
1438    copymemory(@inject[position2],outp,length(outp));
1439    inc(position,length(outp));
1440    inc(position2,length(outp));
1441
1442    assemble('RET',position,outp);
1443    copymemory(@inject[position2],outp,length(outp));
1444    inc(position,length(outp));
1445    inc(position2,length(outp));
1446
1447
1448    //call the routine
1449
1450    if not writeprocessmemory(processhandle,injectionlocation,@inject[0],position2,x) then raise exception.Create('Failed to inject the dll loader');
1451   
1452    {$ifndef standalonetrainer}
1453    {$ifndef net}   
1454
1455    useapctoinjectdll:=false;
1456    if useapctoinjectdll then
1457    begin
1458      showmessage('injected code at:'+inttohex(startaddress,8));
1459     
1460      //suspend , message, resume is needed to prevent a crash when it is in a message loop
1461      ntsuspendprocess(processid);
1462      x:=getathreadid(processid);
1463      PostThreadMessage(x,wm_paint,0,0);
1464      CreateRemoteAPC(x,pointer(startaddress));
1465      ntresumeprocess(processid);
1466    end
1467    else
1468
1469    {$endif}
1470    {$endif}
1471    begin     
1472      threadhandle:=createremotethread(processhandle,nil,0,pointer(startaddress),nil,0,x);
1473      if threadhandle=0 then raise exception.Create('Failed to execute the dll loader');
1474
1475      counter:=10000 div 10;
1476      while (waitforsingleobject(threadhandle,10)=WAIT_TIMEOUT) and (counter>0) do
1477      begin
1478        if GetCurrentThreadID = MainThreadID then
1479          CheckSynchronize; //handle sychronize calls while it's waiting
1480           
1481        dec(counter);
1482      end;
1483
1484      if (counter=0) then
1485        raise exception.Create('The injection thread took longer than 10 seconds to execute. Injection routine not freed');
1486
1487      if getexitcodethread(threadhandle,x) then
1488      begin
1489        case x of
1490          1: ;//success
1491          2: raise exception.Create('Failed injecting the DLL');
1492          3: raise exception.Create('Failed executing the function of the dll');
1493          else raise exception.Create('Unknown error during injection');
1494        end;
1495      end; //else unsure, did it work or not , or is it crashing?
1496
1497    end;
1498  finally
1499    FreeLibrary(h);
1500    if injectionlocation<>nil then
1501      virtualfreeex(processhandle,injectionlocation,0,MEM_RELEASE       );
1502  end;
1503
1504end;
1505
1506procedure ToggleOtherWindows;
1507type Tprocesslistitem = record
1508  processid: dword;
1509  processname: string;
1510end;
1511var winhandle: Hwnd;
1512    winprocess: Dword;
1513    i,j: integer;
1514    SNAPHandle: THandle;
1515    ProcessEntry: ProcessEntry32;
1516    Check: Boolean;
1517    processlist: array of Tprocesslistitem;
1518    hideall,hidethisone: boolean;
1519begin
1520  hideall:=false;
1521
1522  allwindowsareback:=false;
1523
1524  if length(windowlist)<>0 then
1525  begin
1526    for i:=0 to length(windowlist)-1 do
1527      showwindow(windowlist[i],SW_SHOW);
1528
1529    setlength(windowlist,0);
1530    allwindowsareback:=true;
1531    exit;
1532  end;
1533
1534  lastactive:=getactivewindow;
1535  lastforeground:=GetForegroundWindow;
1536
1537  if onlyfront then
1538  begin
1539    GetWindowThreadProcessId(lastforeground,addr(winprocess));
1540    if getcurrentprocessid=winprocess then
1541    begin
1542      beep;
1543      sleep(100);
1544      beep;
1545      sleep(100);
1546      exit;
1547    end;
1548
1549    setlength(windowlist,1);
1550    windowlist[0]:=lastforeground;
1551    showwindow(lastforeground,sw_hide);
1552    exit;
1553  end;
1554
1555
1556  if length(donthidelist)>0 then
1557  begin
1558    //first get a process list
1559    SNAPHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
1560    If SnapHandle>0 then
1561    begin
1562      ProcessEntry.dwSize:=SizeOf(ProcessEntry);
1563      Check:=Process32First(SnapHandle,ProcessEntry);
1564      while check do
1565      begin
1566        if processentry.th32ProcessID<>0 then
1567        begin
1568          setlength(processlist,length(processlist)+1);
1569          processlist[length(processlist)-1].processid:=processentry.th32ProcessID;
1570          processlist[length(processlist)-1].processname:=lowercase(ExtractFilename(processentry.szExeFile));
1571        end;
1572        check:=Process32Next(SnapHandle,ProcessEntry);
1573      end;
1574    end else hideall:=true; //else sorry dude, but no exceptions for you, say goodbye to ALL your windows
1575  end else hideall:=true;
1576
1577  winhandle:=getwindow(GetForegroundWindow,GW_HWNDFIRST);
1578
1579  while winhandle<>0 do
1580  begin
1581    GetWindowThreadProcessId(winhandle,addr(winprocess));
1582
1583    if (winprocess<>getCurrentProcessID) {and (winprocess<>3600) }then
1584    begin
1585      if isWindowVisible(winhandle) then
1586      begin
1587        hidethisone:=true;
1588        if not hideall then
1589        begin
1590          //see if you can hide it or not
1591          //check this window process with the process list
1592          //and then see if the processname equals an item from the donthide list
1593          for i:=0 to length(processlist)-1 do
1594            if processlist[i].processid=winprocess then
1595            begin
1596              //found the process id, now check if the processname of this process equals an item from the list
1597              for j:=0 to length(donthidelist)-1 do
1598                if processlist[i].processname=donthidelist[j] then //it's in so do not hide
1599                begin
1600                  hidethisone:=false;
1601                  break;
1602                end;
1603              break;
1604            end;
1605        end;
1606
1607
1608
1609        if hidethisone then
1610        begin
1611          showwindow(winhandle,SW_HIDE);
1612//          setwindowpos(winhandle,0,0,0,0,0,SWP_HIDEWINDOW or SWP_NOREPOSITION or SWP_NOSIZE   or SWP_NOZORDER or SWP_NOACTIVATE       or SWP_NOREDRAW or SWP_NOSENDCHANGING);
1613          setlength(windowlist,length(windowlist)+1);
1614          windowlist[length(windowlist)-1]:=winhandle;
1615        end;
1616     //   showwindow(winhandle,sw_show); //remove this for real version
1617      end;
1618    end;
1619
1620    winhandle:=getwindow(winhandle,GW_HWNDNEXT);
1621  end;
1622
1623 // application.BringToFront;
1624end;
1625
1626function GetSystemType: Integer;  //from Stuart Johnson with a little change by me
1627const
1628 { operating system constants }
1629
1630 cOsUnknown = 999999;
1631 cOsWin95 = 0;
1632 cOsWin98 = 1;
1633 cOsWin98SE = 2;
1634 cOsWinME = 3;
1635 cOsWinNT = 4;
1636 cOsWin2000 = 5;
1637 cOsWinXP = 6;
1638 cOsNewer = 7;
1639
1640var
1641 osVerInfo : TOSVersionInfo;
1642 majorVer, minorVer : Integer;
1643
1644begin
1645 if overridedebug then
1646 begin
1647   result:=cOsWinXP;
1648   exit;
1649 end;
1650
1651{ set operating system type flag }
1652 osVerInfo.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
1653 if GetVersionEx(osVerInfo) then
1654   begin
1655     majorVer := osVerInfo.dwMajorVersion;
1656     minorVer := osVerInfo.dwMinorVersion;
1657     case osVerInfo.dwPlatformId of
1658       VER_PLATFORM_WIN32_NT : { Windows NT/2000 }
1659         begin
1660           if majorVer <= 4 then
1661             result := cOsWinNT
1662           else
1663             if (majorVer = 5) AND (minorVer= 0) then
1664               result := cOsWin2000
1665             else
1666               if (majorVer = 5) AND (minorVer = 1) then
1667                 result := cOsWinXP
1668             else if (majorver > 5) then result:=cOsNewer
1669           else
1670           result := cOsUnknown;
1671         end; {case }
1672     VER_PLATFORM_WIN32_WINDOWS : { Windows 9x/ME }
1673       begin
1674         if (majorVer = 4) AND (minorVer = 0) then
1675           result := cOsWin95
1676         else
1677           if (majorVer = 4) AND (minorVer = 10) then
1678             begin
1679               if osVerInfo.szCSDVersion[1] = 'A' then
1680                 result := cOsWin98SE
1681               else
1682                  result := cOsWin98;
1683               end {if Version = 'A'}
1684             else
1685               if (majorVer = 4) AND (minorVer = 90) then
1686                 result := cOsWinME
1687               else
1688                  result := cOsUnknown;
1689       end; {case VER_PLATFORM_WIN32_WINDOWS}
1690     else
1691      result := cOsUnknown;
1692   end;
1693 end
1694else
1695  result := cOsUnknown;
1696end;
1697
1698
1699
1700function KeyToStr(key:word):string;
1701begin
1702  case key of
1703    VK_BACK     : result:='Backspace';
1704    VK_TAB      : result:='Tab';
1705    VK_CLEAR    : result:='Clear';
1706    VK_RETURN   : result:='Enter';
1707    VK_PAUSE    : result:='Pause';
1708    VK_CAPITAL  : result:='Caps Lock';
1709    VK_ESCAPE   : result:='Esc';
1710    VK_SPACE    : result:='Space bar';
1711    VK_PRIOR    : result:='Page Up';
1712    VK_NEXT     : result:='Page Down';
1713    VK_END      : result:='End';
1714    VK_HOME     : result:='Home';
1715    VK_LEFT     : result:='Left Arrow';
1716    VK_UP       : result:='Up Arrow';
1717    VK_RIGHT    : result:='Right Arrow';
1718    VK_DOWN     : result:='Down Arrow';
1719    VK_SELECT   : result:='Select';
1720    VK_PRINT    : result:='Print';
1721    VK_EXECUTE  : result:='Execute';
1722    VK_SNAPSHOT : result:='Print Screen';
1723    VK_INSERT   : result:='Insert';
1724    VK_DELETE   : result:='Delete';
1725    VK_HELP     : result:='Help';
1726    VK_LWIN     : result:='Left Windows key';
1727    VK_RWIN     : result:='Right Windows key';
1728    VK_APPS     : result:='Applications key';
1729    VK_NUMPAD0  : result:='numeric 0';
1730    VK_NUMPAD1  : result:='numeric 1';
1731    VK_NUMPAD2  : result:='numeric 2';
1732    VK_NUMPAD3  : result:='numeric 3';
1733    VK_NUMPAD4  : result:='numeric 4';
1734    VK_NUMPAD5  : result:='numeric 5';
1735    VK_NUMPAD6  : result:='numeric 6';
1736    VK_NUMPAD7  : result:='numeric 7';
1737    VK_NUMPAD8  : result:='numeric 8';
1738    VK_NUMPAD9  : result:='numeric 9';
1739    VK_MULTIPLY : result:='numeric *';
1740    VK_ADD      : result:='numeric +';
1741    VK_SEPARATOR : result:='numeric Separator';
1742    VK_SUBTRACT : result:='numeric -';
1743    VK_DECIMAL  : result:='numeric .';
1744    VK_DIVIDE   : result:='numeric /';
1745    VK_F1       : result:='F1';
1746    VK_F2       : result:='F2';
1747    VK_F3       : result:='F3';
1748    VK_F4       : result:='F4';
1749    VK_F5       : result:='F5';
1750    VK_F6       : result:='F6';
1751    VK_F7       : result:='F7';
1752    VK_F8       : result:='F8';
1753    VK_F9       : result:='F9';
1754    VK_F10      : result:='F10';
1755    VK_F11      : result:='F11';
1756    VK_F12      : result:='F12';
1757    VK_F13      : result:='F13';
1758    VK_F14      : result:='F14';
1759    VK_F15      : result:='F15';
1760    VK_F16      : result:='F16';
1761    VK_F17      : result:='F17';
1762    VK_F18      : result:='F18';
1763    VK_F19      : result:='F19';
1764    VK_F20      : result:='F20';
1765    VK_F21      : result:='F21';
1766    VK_F22      : result:='F22';
1767    VK_F23      : result:='F23';
1768    VK_F24      : result:='F24';
1769    VK_NUMLOCK  : result:='Num Lock';
1770    VK_SCROLL   : result:='Scroll Lock';
1771    48..57      : result:=chr(key);
1772    65..90      : result:=chr(key);
1773    else  result:='#'+IntToStr(key);
1774  end;
1775
1776end;
1777
1778procedure decimal(var key: char); //removed
1779begin
1780{
1781  case key of
1782    chr(8)   : ;
1783    chr(16)  : ;
1784    '0'..'9' : ;
1785    else key:=chr(0);
1786  end;
1787  }
1788end;
1789
1790procedure hexadecimal(var key: char);  //removed
1791begin
1792  {case key of
1793    chr(8)   : ;
1794    chr(16)  : ;
1795    'A'..'F' : ;
1796    'a'..'f' : key:=uppercase(key)[1];
1797    '0'..'9' : ;
1798    else key:=chr(0);
1799  end; }
1800end;
1801
1802function ByteStringToText(s: string;hex: boolean):string;
1803var temp: tbytes;
1804    i,j: integer;
1805begin
1806  ConvertStringToBytes(s,hex,temp);
1807  result:='';
1808
1809  for i:=0 to length(temp)-1 do
1810    if temp[i]>$13 then
1811      result:=result+chr(temp[i]);
1812end;
1813
1814
1815function ByteStringToDouble(s: string;hex: boolean):double;
1816var temp: tbytes;
1817    temp2: double;
1818    p: ^byte;
1819    i,j: integer;
1820begin
1821  ConvertStringToBytes(s,hex,temp);
1822  p:=@temp2;
1823
1824  if length(temp)<8 then
1825  begin
1826    j:=length(temp);
1827    setlength(temp,8);
1828    for i:=j to 7 do
1829      temp[i]:=0;
1830  end;
1831
1832  for i:=0 to length(temp)-1 do
1833  begin
1834    if temp[i]=-1 then temp[i]:=0;
1835
1836    p^:=byte(temp[i]);
1837    inc(p);
1838  end;
1839
1840  result:=temp2;
1841end;
1842
1843
1844function ByteStringToSingle(s: string;hex: boolean):single;
1845var temp: tbytes;
1846    temp2: single;
1847    p: ^byte;
1848    i,j: integer;
1849begin
1850  ConvertStringToBytes(s,hex,temp);
1851  p:=@temp2;
1852
1853  if length(temp)<4 then
1854  begin
1855    j:=length(temp);
1856    setlength(temp,4);
1857    for i:=j to 3 do
1858      temp[i]:=0;
1859  end;
1860
1861  for i:=0 to length(temp)-1 do
1862  begin
1863    if temp[i]=-1 then temp[i]:=0;
1864
1865    p^:=byte(temp[i]);
1866    inc(p);
1867  end;
1868
1869  result:=temp2;
1870end;
1871
1872function ByteStringToInt(s: string;hex: boolean):int64;
1873var temp: tbytes;
1874    i: integer;
1875    power: integer;
1876
1877begin
1878  ConvertStringToBytes(s,hex,temp);
1879  power:=0;
1880  result:=0;
1881
1882  for i:=0 to length(temp)-1 do
1883  begin
1884    result:=result+(temp[i]*trunc(math.power(256,power)));
1885    inc(power);
1886  end;
1887end;
1888
1889function VarToBytes(v: pointer; size: integer): string;
1890var p: ^byte;
1891    j,k: integer;
1892    res: array of string;
1893begin
1894  result:='';
1895  p:=v;
1896
1897  setlength(res,size);
1898
1899  for k:=0 to size-1 do
1900  begin
1901    res[k]:=inttohex(p^,2);
1902    inc(p);
1903  end;
1904
1905  j:=size;
1906  for k:=size-1 to 1 do
1907    if res[k]='00' then dec(j);
1908
1909  for k:=0 to j-1 do
1910    result:=result+res[k]+' ';
1911
1912  result:=copy(result,1,length(result)-1);
1913end;
1914
1915function BinToInt(s: string): int64;
1916var i: integer;
1917begin
1918  result:=0;
1919  for i:=length(s) downto 1 do
1920    if s[i]='1' then result:=result+trunc(power(2,length(s)-i ));
1921end;
1922
1923function Inttobin(i: int64): string;
1924var temp,temp2: string;
1925    j: integer;
1926begin
1927  temp:='';
1928  while i>0 do
1929  begin
1930    if (i mod 2)>0 then temp:=temp+'1'
1931                   else temp:=temp+'0';
1932    i:=i div 2;
1933  end;
1934
1935  temp2:='';
1936  for j:=length(temp) downto 1 do
1937    temp2:=temp2+temp[j];
1938  result:=temp2;
1939end;
1940
1941
1942
1943function getbit(bitnr: integer; bt: dword):integer;
1944begin
1945  result:=(bt shr bitnr) and 1;
1946end;
1947
1948procedure setbit(bitnr: integer; var bt: dword;state:integer); overload;
1949{
1950 pre: bitnr=bit between 0 and 7
1951         bt=pointer to the byte
1952 post: bt has the bit set specified in state
1953 result: bt has a bit set or unset
1954}
1955begin
1956  bt:=bt and (not (1 shl bitnr));
1957  bt:=bt or (state shl bitnr);
1958end;
1959
1960procedure setbit(bitnr: integer; var bt: Byte;state:integer); overload;
1961{
1962 pre: bitnr=bit between 0 and 7
1963         bt=pointer to the byte
1964 post: bt has the bit set specified in state
1965 result: bt has a bit set or unset
1966}
1967var d: dword;
1968begin
1969  d:=bt;
1970  setbit(bitnr,d,state);
1971  bt:=d;
1972end;
1973
1974function eflags_setCF(flagvalue: dword; value: integer): DWORD;
1975begin
1976  result:=flagvalue and (not (1 shl 0)) or (value shl 0);
1977end;
1978
1979function eflags_setPF(flagvalue: dword; value: integer): DWORD;
1980begin
1981  result:=flagvalue and (not (1 shl 2)) or (value shl 2);
1982end;
1983
1984function eflags_setAF(flagvalue: dword; value: integer): DWORD;
1985begin
1986  result:=flagvalue and (not (1 shl 4)) or (value shl 4);
1987end;
1988
1989function eflags_setZF(flagvalue: dword; value: integer): DWORD;
1990begin
1991  result:=flagvalue and (not (1 shl 6)) or (value shl 6);
1992end;
1993
1994function eflags_setSF(flagvalue: dword; value: integer): DWORD;
1995begin
1996  result:=flagvalue and (not (1 shl 7)) or (value shl 7);
1997end;
1998
1999function eflags_setTF(flagvalue: dword; value: integer): DWORD;
2000begin
2001  result:=flagvalue and (not (1 shl 8)) or (value shl 8);
2002end;
2003
2004function eflags_setIF(flagvalue: dword; value: integer): DWORD;
2005begin
2006  result:=flagvalue and (not (1 shl 9)) or (value shl 9);
2007end;
2008
2009function eflags_setDF(flagvalue: dword; value: integer): DWORD;
2010begin
2011  result:=flagvalue and (not (1 shl 10)) or (value shl 10);
2012end;
2013
2014function eflags_setOF(flagvalue: dword; value: integer): DWORD;
2015begin
2016  result:=flagvalue and (not (1 shl 11)) or (value shl 11);
2017end;
2018
2019function eflags_setIOPL(flagvalue: dword; value: integer): DWORD;
2020begin
2021  result:=flagvalue and (not (3 shl 12)) or (value shl 12);
2022end;
2023
2024function eflags_setNT(flagvalue: dword; value: integer): DWORD;
2025begin
2026  result:=flagvalue and (not (1 shl 14)) or (value shl 14);
2027end;
2028
2029function eflags_setRF(flagvalue: dword; value: integer): DWORD;
2030begin
2031  result:=flagvalue and (not (1 shl 16)) or (value shl 16);
2032end;
2033
2034function eflags_setVM(flagvalue: dword; value: integer): DWORD;
2035begin
2036  result:=flagvalue and (not (1 shl 17)) or (value shl 17);
2037end;
2038
2039function eflags_setAC(flagvalue: dword; value: integer): DWORD;
2040begin
2041  result:=flagvalue and (not (1 shl 18)) or (value shl 18);
2042end;
2043
2044function eflags_setVIF(flagvalue: dword; value: integer): DWORD;
2045begin
2046  result:=flagvalue and (not (1 shl 19)) or (value shl 19);
2047end;
2048
2049function eflags_setVIP(flagvalue: dword; value: integer): DWORD;
2050begin
2051  result:=flagvalue and (not (1 shl 20)) or (value shl 20);
2052end;
2053
2054function eflags_setID(flagvalue: dword; value: integer): DWORD;
2055begin
2056  result:=flagvalue and (not (1 shl 21)) or (value shl 21);
2057end;
2058
2059function undolastscan(valtype: integer;hexadecimal:boolean): integer;
2060begin
2061  deletefile(CheatEngineDir+'Memory.tmp');
2062  deletefile(CheatEngineDir+'Addresses.tmp');
2063
2064  renamefile(CheatEngineDir+'Memory.UNDO',CheatEngineDir+'Memory.tmp');
2065  renamefile(CheatEngineDir+'Addresses.UNDO',CheatEngineDir+'Addresses.tmp');
2066
2067  assignfile(addressfile,CheatEngineDir+'Addresses.tmp');
2068  assignfile(memoryfile,CheatEngineDir+'Memory.tmp');
2069end;
2070
2071function AvailMem:dword;
2072var x: _MEMORYSTATUS;
2073begin
2074  x.dwLength:=sizeof(x);
2075  GlobalMemoryStatus(x);
2076
2077  if x.dwAvailVirtual>(x.dwAvailPhys+x.dwAvailPageFile) then
2078    result:=x.dwAvailPhys+x.dwAvailPageFile
2079  else
2080    result:=x.dwAvailVirtual;
2081
2082end;
2083
2084procedure RemoveAddress(address: Dword;bit: Byte; vartype: Integer);
2085type bitaddress = record
2086  address: dword;
2087  bit: dword;
2088end;
2089
2090var
2091
2092    Addresses: Array [1..number] of Dword;
2093    BAddress: Array [1..number] of BitAddress;
2094    Memory: Array [1..8*number] of Byte;
2095    i,j: Integer;
2096
2097    str: pchar;
2098
2099    found: boolean;
2100    check,check2: Integer;
2101
2102
2103begin
2104  assignfile(memoryfile,CheatEngineDir+'Memory.TMP');
2105  assignfile(addressfile,CheatEngineDir+'Addresses.TMP');
2106  reset(memoryfile,1);
2107  reset(addressfile,1);
2108
2109  assignfile(newmemoryfile,CheatEngineDir+'Memory2.TMP');
2110  assignfile(newaddressfile,CheatEngineDir+'Address2.TMP');
2111  rewrite(newmemoryfile,1);
2112  rewrite(newaddressfile,1);
2113
2114  blockread(addressfile,memory,7,check);
2115  blockwrite(newaddressfile,memory,7,check);
2116
2117  found:=false;
2118  i:=0;
2119
2120  if vartype=7 then  //text scan
2121  begin
2122    i:=filesize(memoryfile);
2123
2124    getmem(str,i+1);
2125    blockread(memoryfile,pointer(str)^,i,check);
2126    str[i]:=chr(0);
2127    blockwrite(newmemoryfile,pointer(str)^,i,check);
2128
2129    check:=4*number;
2130    while (check=4*number) do
2131    begin
2132      blockread(addressfile,addresses,4*number,check);
2133      i:=0;
2134      j:=0;
2135      while (i<check div 4) do
2136      begin
2137        inc(i);
2138        if addresses[i]<>address then //if it's not the selected address write it else dont write it.
2139          blockwrite(newaddressfile,addresses[i],4,check2);
2140      end;
2141    end;
2142  end
2143  else
2144  if vartype<>5 then
2145  begin
2146    check:=4*number;
2147    while ((not found) and (check=4*number)) do
2148    begin
2149      blockread(addressfile,addresses,4*number,check);
2150      i:=0;
2151      while (not found) and (i<(check div 4)) do
2152      begin
2153        inc(i);
2154        if addresses[i]=address then
2155        begin
2156          found:=true;
2157          break;
2158        end;
2159      end;
2160
2161      if not found then
2162      begin
2163        blockwrite(newaddressfile,addresses,4*number,check2);
2164        case vartype of
2165          0:    begin //byte
2166                  blockread(memoryfile,memory,number,check2);
2167                  blockwrite(newmemoryfile,memory,check2,check2);
2168                end;
2169
2170          1:    begin //word
2171                  blockread(memoryfile,memory,2*number,check2);
2172                  blockwrite(newmemoryfile,memory,check2,check2);
2173                end;
2174
2175          2:    begin //dword
2176                  blockread(memoryfile,memory,4*number,check2);
2177                  blockwrite(newmemoryfile,memory,check2,check2);
2178                end;
2179
2180
2181          3:    begin //float
2182                  blockread(memoryfile,memory,4*number,check2);
2183                  blockwrite(newmemoryfile,memory,check2,check2);
2184                end;
2185
2186          4:    begin //double
2187                  blockread(memoryfile,memory,8*number,check2);
2188                  blockwrite(newmemoryfile,memory,check2,check2);
2189                end;
2190
2191          6:    begin //int64
2192                  blockread(memoryfile,memory,8*number,check2);
2193                  blockwrite(newmemoryfile,memory,check2,check2);
2194                end;
2195
2196
2197          //bit doesnt come here
2198        end;
2199      end;
2200    end;
2201
2202    if found then
2203    begin
2204      for j:=i to number-1 do
2205        addresses[j]:=addresses[j+1];
2206
2207      blockwrite(newaddressfile,addresses,check-4,check2);
2208
2209      case vartype of
2210        0:    begin //byte
2211                blockread(memoryfile,memory,number,check2);
2212                for j:=i to number-1 do memory[j]:=memory[j+1];
2213                blockwrite(newmemoryfile,memory,check2-1,check2);
2214              end;
2215
2216        1:    begin //word
2217                blockread(memoryfile,memory,2*number,check2);
2218                for j:=i to number-4 do
2219                begin
2220                  memory[j]:=memory[j+2];
2221                  memory[j+1]:=memory[j+3];
2222                end;
2223                blockwrite(newmemoryfile,memory,check2-2,check2);
2224              end;
2225
2226        2:    begin //dword
2227                blockread(memoryfile,memory,4*number,check2);
2228                for j:=i to number-8 do
2229                begin
2230                  memory[j]:=memory[j+4];
2231                  memory[j+1]:=memory[j+5];
2232                  memory[j+2]:=memory[j+6];
2233                  memory[j+3]:=memory[j+7];
2234                end;
2235
2236                blockwrite(newmemoryfile,memory,check2-4,check2);
2237              end;
2238
2239
2240        3:    begin //float
2241                blockread(memoryfile,memory,4*number,check2);
2242                for j:=i to number-8 do
2243                begin
2244                  memory[j]:=memory[j+4];
2245                  memory[j+1]:=memory[j+5];
2246                  memory[j+2]:=memory[j+6];
2247                  memory[j+3]:=memory[j+7];
2248                end;
2249                blockwrite(newmemoryfile,memory,check2-4,check2);
2250              end;
2251
2252        4:    begin //double
2253                blockread(memoryfile,memory,8*number,check2);
2254                for j:=i to number-16 do
2255                begin
2256                  memory[j]:=memory[j+8];
2257                  memory[j+1]:=memory[j+9];
2258                  memory[j+2]:=memory[j+10];
2259                  memory[j+3]:=memory[j+11];
2260                  memory[j+4]:=memory[j+12];
2261                  memory[j+5]:=memory[j+13];
2262                  memory[j+6]:=memory[j+14];
2263                  memory[j+7]:=memory[j+15];
2264                end;
2265                blockwrite(newmemoryfile,memory,check2-8,check2);
2266              end;
2267
2268        6:    begin //Int64
2269                blockread(memoryfile,memory,8*number,check2);
2270                for j:=i to number-16 do
2271                begin
2272                  memory[j]:=memory[j+8];
2273                  memory[j+1]:=memory[j+9];
2274                  memory[j+2]:=memory[j+10];
2275                  memory[j+3]:=memory[j+11];
2276                  memory[j+4]:=memory[j+12];
2277                  memory[j+5]:=memory[j+13];
2278                  memory[j+6]:=memory[j+14];
2279                  memory[j+7]:=memory[j+15];
2280                end;
2281                blockwrite(newmemoryfile,memory,check2-8,check2);
2282              end;
2283
2284
2285        end;
2286
2287        //and now just copy the addresses till the end
2288        check:=4*number;
2289        while (check=4*number) do
2290        begin
2291          blockread(addressfile,addresses,4*number,check);
2292          blockwrite(newaddressfile,addresses,check,check);
2293        end;
2294
2295        //and same for memory
2296        check:=4*number;
2297        while (check=4*number) do
2298        begin
2299          blockread(memoryfile,addresses,4*number,check);
2300          blockwrite(newaddressfile,addresses,check,check);
2301        end;
2302    end;
2303
2304  end;
2305
2306  closefile(memoryfile);
2307  closefile(addressfile);
2308  closefile(newmemoryfile);
2309  closefile(newaddressfile);
2310
2311  deletefile(CheatEngineDir+'Memory.UNDO');
2312  deletefile(CheatEngineDir+'Addresses.UNDO');
2313  renamefile(CheatEngineDir+'Memory.tmp',cheatenginedir+'Memory.UNDO');
2314  renamefile(CheatEngineDir+'Addresses.tmp',CheatEngineDir+'Addresses.UNDO');
2315  renamefile(CheatEngineDir+'Memory2.tmp',CheatEngineDir+'Memory.TMP');
2316  Renamefile(CheatengineDir+'Address2.TMP',CheatEngineDir+'Addresses.TMP');
2317
2318
2319end;
2320
2321procedure Open_Process;
2322begin
2323  {$ifndef netclient}
2324  ProcessHandler.ProcessHandle:=NewKernelHandler.OpenProcess(PROCESS_ALL_ACCESS,false,ProcessID);
2325  le:=GetLastError;
2326  {$endif}
2327end;
2328          {
2329function MakeAddressWritable(address: dword):boolean;
2330var buf,x:dword;
2331begin
2332  result:=false;
2333  if ReadProcessMemory(processhandle,pointeR(address),@buf,4,x) then
2334  begin
2335    if ReadProcessMemory(processhandle,pointer(((address div $1000)*4)+$c0000000),@buf,4,x) then
2336    begin
2337      if copyonwrite then
2338        buf:=(buf or $200) //when you write to it it will copy the page and give that to the process in writable state
2339      else
2340        buf:=(buf or $2);  //just make it writable, even if it is shared
2341
2342      result:=WriteProcessMemory(processhandle,pointer(((address div $1000)*4)+$c0000000),@buf,4,x);
2343    end;
2344  end;
2345end;
2346           }
2347
2348      {
2349procedure quicksortmemoryregions(lo,hi: integer);
2350var i,j: integer;
2351    x,h: TMemoryRegion;
2352begin
2353  i:=lo;
2354  j:=hi;
2355
2356  x:=memoryregion[(lo+hi) div 2];
2357
2358  repeat
2359    while (memoryregion[i].BaseAddress<x.BaseAddress) do inc(i);
2360    while (memoryregion[j].BaseAddress>x.BaseAddress) do dec(j);
2361
2362    if i<=j then
2363    begin
2364      h:=memoryregion[i];
2365      memoryregion[i]:=memoryregion[j];
2366      memoryregion[j]:=h;
2367      inc(i);
2368      dec(j);
2369    end;
2370
2371  until i>j;
2372
2373  if (lo<j) then quicksortmemoryregions(lo,j);
2374  if (i<hi) then quicksortmemoryregions(i,hi);
2375end;
2376         }
2377
2378     {
2379procedure GetProcessListSmall(ProcessList: TListBox);
2380Var SNAPHandle: THandle;
2381    ProcessEntry: ProcessEntry32;
2382    Check: Boolean;
2383begin
2384  processlist.clear;
2385
2386  processlist.Sorted:=false;
2387  SNAPHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
2388  If SnapHandle>0 then
2389  begin
2390    ProcessEntry.dwSize:=SizeOf(ProcessEntry);
2391    Check:=Process32First(SnapHandle,ProcessEntry);
2392    while check do
2393    begin
2394      if processentry.th32ProcessID<>0 then
2395        ProcessList.Items.Add(ExtractFilename(processentry.szExeFile));
2396
2397      check:=Process32Next(SnapHandle,ProcessEntry);
2398    end;
2399  end else raise exception.Create('I can''t get the process list. You are propably using windows NT. Use the window list instead!');
2400end;   }
2401
2402
2403procedure GetProcessList(ProcessList: TListBox);
2404var sl: tstringlist;
2405    i: integer;
2406begin
2407  sl:=tstringlist.create;
2408  try
2409    processlist.Sorted:=false;
2410    for i:=0 to processlist.Items.count-1 do
2411      if processlist.Items.Objects[i]<>nil then
2412        freemem(pointer(processlist.Items.Objects[i]));
2413
2414    processlist.Items.Clear;
2415
2416   
2417    GetProcessList(sl);
2418    processlist.Items.AddStrings(sl);
2419  finally
2420    sl.free;
2421  end;
2422end;
2423
2424
2425function GetFirstModuleName(processid: dword): string;
2426var
2427  SNAPHandle: THandle;
2428  check: boolean;
2429  ModuleEntry: MODULEENTRY32;
2430begin
2431  SNAPHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,processid);
2432  if SNAPHandle<>0 then
2433  begin
2434    ModuleEntry.dwSize:=sizeof(moduleentry);
2435    if Module32First(snaphandle,ModuleEntry) then
2436      result:=moduleentry.szExePath
2437    else
2438      result:='';
2439
2440    closehandle(SNAPHandle);
2441  end;
2442end;
2443
2444procedure GetProcessList(ProcessList: TStrings);
2445Var SNAPHandle: THandle;
2446    ProcessEntry: ProcessEntry32;
2447    Check: Boolean;
2448
2449    HI: HICON;
2450    ProcessListInfo: PProcessListInfo;
2451    i: integer;
2452    s: string;
2453begin
2454  HI:=0;
2455
2456  for i:=0 to processlist.count-1 do
2457    if processlist.Objects[i]<>nil then
2458      freemem(pointer(processlist.Objects[i]));
2459
2460  processlist.clear;
2461
2462
2463  SNAPHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
2464  If SnapHandle>0 then
2465  begin
2466    ProcessEntry.dwSize:=SizeOf(ProcessEntry);
2467    Check:=Process32First(SnapHandle,ProcessEntry);
2468    while check do
2469    begin
2470      if getprocessicons then
2471      begin
2472        HI:=ExtractIcon(hinstance,ProcessEntry.szExeFile,0);
2473        if HI=0 then
2474        begin
2475          //alternative method:
2476          if processentry.th32ProcessID>0 then
2477          begin
2478            s:=GetFirstModuleName(processentry.th32ProcessID);
2479            HI:=ExtractIcon(hinstance,pchar(s),0);
2480          end;
2481        end;
2482      end;
2483
2484
2485      if not (ProcessesWithIconsOnly and (hi=0)) then
2486      begin
2487        if processentry.th32ProcessID<>0 then
2488        begin
2489         // processinfo
2490          getmem(ProcessListInfo,sizeof(TProcessListInfo));
2491          ProcessListInfo.processID:=processentry.th32ProcessID;
2492          ProcessListInfo.processIcon:=HI;
2493
2494          ProcessList.AddObject(IntTohex(processentry.th32ProcessID,8)+'-'+ExtractFilename(processentry.szExeFile), TObject(ProcessListInfo));
2495        end;
2496      end;
2497
2498      check:=Process32Next(SnapHandle,ProcessEntry);
2499    end;
2500    closehandle(snaphandle);
2501  end else raise exception.Create('I can''t get the process list. You are propably using windows NT. Use the window list instead!');
2502end;
2503
2504procedure GetWindowList(ProcessList: TListBox{; var ArrIcons: TBytes});
2505var previouswinhandle, winhandle: Hwnd;
2506    winprocess: Dword;
2507    temp: Pchar;
2508    wintitle: string;
2509
2510    x: tstringlist;
2511    i:integer;
2512
2513    ProcessListInfo: PProcessListInfo;
2514begin
2515  getmem(temp,101);
2516  try
2517    x:=tstringlist.Create;
2518
2519    for i:=0 to processlist.items.count-1 do
2520      if processlist.items.Objects[i]<>nil then
2521        freemem(pointer(processlist.items.Objects[i]));
2522    processlist.clear;
2523
2524    winhandle:=getwindow(getforegroundwindow,GW_HWNDFIRST);
2525
2526    i:=0;
2527    while (winhandle<>0) and (i<10000) do
2528    begin
2529      GetWindowThreadProcessId(winhandle,addr(winprocess));
2530      temp[0]:=#0;
2531      getwindowtext(winhandle,temp,100);
2532      temp[100]:=#0;
2533      wintitle:=temp;
2534
2535      if length(wintitle)>0 then
2536      begin
2537        getmem(ProcessListInfo,sizeof(TProcessListInfo));
2538        ProcessListInfo.processID:=winprocess;
2539        ProcessListInfo.processIcon:=SendMessage(winhandle,WM_GETICON,ICON_SMALL,0);
2540        if ProcessListInfo.processIcon=0 then
2541          ProcessListInfo.processIcon:=SendMessage(winhandle,WM_GETICON,ICON_BIG,0);
2542
2543        x.AddObject(IntTohex(winprocess,8)+'-'+wintitle,TObject(ProcessListInfo));
2544      end;
2545
2546      previouswinhandle:=winhandle;
2547      winhandle:=getwindow(winhandle,GW_HWNDNEXT);
2548
2549      if winhandle=previouswinhandle then break;
2550     
2551      inc(i);
2552    end;
2553
2554    x.Sort;
2555    processlist.Items.Assign(x);
2556  finally
2557    freemem(temp);
2558  end;
2559end;
2560
2561function GetCEdir:string;
2562begin
2563  CheatEngineDir:=ExtractFilePath(application.ExeName);
2564  result:=CheatEngineDir;
2565end;
2566
2567function GetWinDir:string;
2568var x: pchar;
2569begin
2570  getmem(x,200);
2571  if GetWindowsDirectory(x,200)>0 then
2572  begin
2573    result:=x;
2574    WindowsDir:=x;
2575  end;
2576  freemem(x);
2577end;
2578
2579Procedure Shutdown;
2580//This will erase the temporary files and close the processhandle (In case it doesnt happen automatically)
2581begin
2582  deletefile(CheatEngineDir+'Memory.TMP');
2583  deletefile(CheatEngineDir+'Addresses.TMP');
2584  deletefile(CheatEngineDir+'Memory.UNDO');
2585  deletefile(CheatEngineDir+'Addresses.UNDO');
2586  freemem(memory);
2587 // Closehandle(processhandle);
2588
2589end;
2590
2591procedure ConvertStringToBytes(scanvalue:string; hex:boolean;var bytes: TBytes);
2592{
2593Converts a given string into a array of TBytes.
2594TBytes are not pure bytes, they can hold -1, which indicates a wildcard
2595}
2596var i,j,k: integer;
2597    helpstr:string;
2598begin
2599  setlength(bytes,0);
2600  if length(scanvalue)=0 then exit;
2601
2602  while scanvalue[length(scanvalue)]=' ' do
2603    scanvalue:=copy(scanvalue,1,length(scanvalue)-1);
2604
2605  if (pos('-',scanvalue)>0) or (pos(' ',scanvalue)>0) then
2606  begin
2607    //syntax is xx-xx-xx or xx xx xx
2608    j:=1;
2609    k:=0;
2610    scanvalue:=scanvalue+' ';
2611
2612    for i:=1 to length(scanvalue) do
2613    begin
2614      if (scanvalue[i]=' ') or (scanvalue[i]='-') then
2615      begin
2616        helpstr:=copy(scanvalue,j,i-j);
2617        j:=i+1;
2618        setlength(bytes,k+1);
2619        try
2620          if hex then bytes[k]:=strtoint('$'+helpstr)
2621                 else bytes[k]:=strtoint(helpstr);
2622        except
2623          bytes[k]:=-1;
2624          //if it is not a '-' or ' ' or a valid value then I assume it is a wildcard.(I know, retarded)
2625        end;
2626        inc(k);
2627      end;
2628    end;
2629  end else
2630  begin
2631    //syntax is xxxxxx
2632    k:=0;
2633    j:=1;
2634    for i:=1 to length(scanvalue) do
2635    begin
2636      if (i mod 2)=0 then
2637      begin
2638        helpstr:=copy(scanvalue,j,i-j+1);
2639        j:=i+1;
2640        setlength(bytes,k+1);
2641        try
2642          bytes[k]:=strtoint('$'+helpstr);
2643        except
2644          bytes[k]:=-1;
2645        end;
2646        inc(k);
2647      end;
2648    end;
2649  end;
2650end;
2651
2652
2653
2654procedure rewritedata(processhandle: thandle; address:dword; buffer: pointer; size:dword);
2655var written: dword;
2656    original,a: dword;
2657begin
2658//make writable, write, restore, flush
2659  VirtualProtectEx(processhandle,  pointer(address),size,PAGE_EXECUTE_READWRITE,original);
2660  writeprocessmemory(processhandle,pointer(address),buffer,size,written);
2661  VirtualProtectEx(processhandle,pointer(address),size,original,a);
2662end;
2663
2664procedure rewritecode(processhandle: thandle; address:dword; buffer: pointer; size:dword);
2665begin
2666  rewritedata(processhandle,address,buffer,size);
2667  FlushInstructionCache(processhandle,pointer(address),size);
2668end;
2669
2670function HasHyperthreading: boolean;
2671var a,b,c,d: dword;
2672begin
2673  result:=false;
2674  asm
2675    pushad
2676    mov eax,0
2677    cpuid
2678    mov a,eax
2679    mov b,ebx
2680    mov c,ecx
2681    mov d,edx
2682    popad
2683  end;
2684
2685  if (b=$756e6547) and (d=$49656e69) and (c=$6c65746e) then
2686  begin
2687    //intel cpu
2688    asm
2689      pushad
2690      mov eax,1
2691      cpuid
2692      mov a,eax
2693      mov b,ebx
2694      mov c,ecx
2695      mov d,edx
2696      popad
2697    end;
2698
2699    if ((d shr 28) and 1)=1 then
2700      result:=true; //it has hyperthreading
2701  end;
2702
2703
2704end;
2705
2706function GetCPUCount: integer;
2707{
2708this function will return how many active cpu cores there are at your disposal
2709}
2710var cpucount: integer;
2711    PA,SA: dword;
2712begin
2713  //get the cpu and system affinity mask, only processmask is used
2714  GetProcessAffinityMask(getcurrentprocess,PA,SA);
2715
2716  cpucount:=0;
2717  while pa>0 do
2718  begin
2719    if (pa mod 2)=1 then inc(cpucount);
2720    pa:=pa div 2;
2721  end;
2722
2723  result:=cpucount;
2724
2725  if result=0 then result:=1;
2726end;
2727
2728function LoadFormPosition(form: Tform; var x: array of integer):boolean;
2729var reg: tregistry;
2730    s: string;
2731    buf: array of integer;
2732    buf2: array [0..100] of byte;
2733    i: integer;
2734    z: integer;
2735begin
2736  result:=false;
2737  reg:=tregistry.create;
2738  try
2739    Reg.RootKey := HKEY_CURRENT_USER;
2740    if Reg.OpenKey('\Software\Cheat Engine',false) then
2741    begin
2742      if reg.valueexists('Save window positions') then
2743        if reg.readbool('Save window positions') = false then exit;
2744    end;
2745
2746    if Reg.OpenKey('\Software\Cheat Engine\Window Positions',false) then
2747    begin
2748      s:=form.Name;
2749      s:=s+' Position';
2750
2751      if reg.ValueExists(s) then
2752      begin
2753
2754        setlength(buf,4+length(x)); //for some reason it checks if
2755
2756        z:=reg.ReadBinaryData(s,buf[0],length(buf)*sizeof(integer));
2757
2758        form.position:=poDesigned;
2759        form.top:=buf[0];
2760        form.Left:=buf[1];
2761        form.width:=buf[2];
2762        form.height:=buf[3];
2763
2764        for i:=0 to length(x)-1 do
2765          x[i]:=buf[4+i];
2766
2767        setlength(buf,0);
2768
2769        result:=true;
2770      end;
2771    end;
2772  finally
2773    reg.free;
2774  end;
2775end;
2776
2777procedure SaveFormPosition(form: Tform; extra: array of integer);
2778{
2779This function will save the position and the optional data in extra to an array element in the registry
2780}
2781var reg: tregistry;
2782    buf: tmemorystream;
2783    temp: integer;
2784    i: integer;
2785    s: string;
2786begin
2787  //save window pos
2788  reg:=tregistry.create;
2789  try
2790    Reg.RootKey := HKEY_CURRENT_USER;
2791
2792    //make sure the option to save is enabled
2793    if Reg.OpenKey('\Software\Cheat Engine',false) then
2794    begin
2795      if reg.valueexists('Save window positions') then
2796        if reg.readbool('Save window positions') = false then exit;
2797    end;
2798
2799   
2800    if Reg.OpenKey('\Software\Cheat Engine\Window Positions',true) then
2801    begin
2802      //registry is open, gather data
2803      buf:=tmemorystream.Create;
2804      try
2805        temp:=form.top;
2806        buf.Write(temp,sizeof(temp));
2807
2808        temp:=form.left;
2809        buf.Write(temp,sizeof(temp));
2810
2811        temp:=form.width;
2812        buf.Write(temp,sizeof(temp));
2813
2814        temp:=form.height;
2815        buf.Write(temp,sizeof(temp));
2816
2817
2818        //save extra data
2819        for i:=0 to length(extra)-1 do
2820          buf.Write(extra[i],sizeof(extra[i]));
2821
2822        //and now save buf to the registry
2823        s:=form.Name;
2824        s:=s+' Position';
2825
2826        reg.WriteBinaryData(s,buf.Memory^,buf.Size);
2827      finally
2828        buf.free;
2829      end;
2830    end;
2831  finally
2832    reg.free;
2833  end;
2834end;
2835
2836function GetRelativeFilePath(filename: string):string;
2837begin
2838  result:=filename;
2839  if pos(uppercase(CheatEngineDir),uppercase(filename))=1 then
2840    result:='.\'+copy(filename,length(CheatEnginedir)+1,length(filename));
2841end;
2842
2843function ConvertHexStrToRealStr(const s: string): string;
2844{
2845Converts a string meant to be a hexadeimcal string to the real way delphi reads
2846it
2847e.g:
2848123 > $123
2849-123 > -$123
2850+123 > +$123
2851#123 > 123
2852+#123 > +123
2853}
2854var ishex: string;
2855    start: integer;
2856    i,j,k: integer;
2857
2858    bytes: string;
2859    t: string;
2860    f: single;
2861    d: double;
2862begin
2863  if s='' then
2864  begin
2865    result:=s;
2866    exit;
2867  end;
2868  start:=1;
2869
2870  ishex:='$';
2871  for i:=start to length(s) do
2872    case s[i] of
2873      '''' , '"' :
2874      begin
2875        //char
2876        if (i+2)<=length(s) then
2877        begin
2878          bytes:='';
2879          for j:=i+2 to length(s) do
2880            if s[j] in ['''','"'] then
2881            begin
2882              bytes:=copy(s,i+1,j-(i+1));
2883
2884              result:='$';
2885              for k:=length(bytes) downto 1 do
2886                result:=result+inttohex(byte(bytes[k]),2);
2887
2888              //result := '$'+inttohex(byte(s[i+1]),2);
2889              exit; //this is it, no further process required, or appreciated...
2890
2891            end;
2892
2893
2894
2895        end;
2896      end;
2897
2898      '#' :
2899      begin
2900        ishex:='';
2901        start:=2;
2902        break;
2903      end;
2904
2905      '(' :
2906      begin
2907        if copy(s,1,5)='(INT)' then
2908        begin
2909          t:=copy(s,6,length(s));
2910          val(t, k,j);
2911          if j=0 then
2912          begin
2913            result:='$'+inttohex(k,8);
2914
2915            if s[1]='-' then
2916              result:='-'+result;
2917
2918            if s[1]='+' then
2919              result:='+'+result;
2920             
2921            exit;
2922          end;
2923        end;
2924
2925        if copy(s,1,8)='(DOUBLE)' then
2926        begin
2927          t:=copy(s,9,length(s));
2928          val(t, d,j);
2929          if j=0 then
2930          begin
2931            result:='$'+inttohex(PINT64(@d)^,8);
2932
2933            if s[1]='-' then
2934              result:='-'+result;
2935
2936            if s[1]='+' then
2937              result:='+'+result;
2938             
2939            exit;
2940          end;
2941        end;
2942
2943        if copy(s,1,7)='(FLOAT)' then
2944        begin
2945          t:=copy(s,8,length(s));
2946          val(t, f,j);
2947          if j=0 then
2948          begin
2949            result:='$'+inttohex(pdword(@f)^,8);
2950
2951            if s[1]='-' then
2952              result:='-'+result;
2953
2954            if s[1]='+' then
2955              result:='+'+result;
2956             
2957            exit;
2958          end;
2959        end;
2960      end;
2961    end;
2962
2963
2964  if s[1]='-' then
2965  begin
2966    result:='-'+ishex+copy(s,start+1,length(s))
2967  end
2968  else
2969  if s[1]='+' then
2970  begin
2971    result:='+'+ishex+copy(s,start+1,length(s));
2972  end
2973  else
2974  begin
2975    result:=ishex+copy(s,start,length(s));
2976  end;
2977end;
2978
2979function HexStrToInt(const S: string): Integer;
2980begin
2981  result:=StrToint(ConvertHexStrToRealStr(s));
2982end;
2983
2984function HexStrToInt64(const S: string): Int64;
2985begin
2986  result:=StrToint64(ConvertHexStrToRealStr(s));
2987end;
2988
2989function isjumporcall(address: dword; var addresstojumpto: dword): boolean;
2990var buf: array [0..31] of byte;
2991    actualread: dword;
2992    i,j: integer;
2993    st: string;
2994    offset: dword;
2995    haserror: boolean;
2996begin
2997{$ifndef standalonetrainer}
2998  result:=false;
2999
3000  if readprocessmemory(processhandle,pointer(address),@buf[0],32,actualread) then
3001  begin
3002    if buf[0] in [$0f,$70..$7f,$e3,$e8,$e9,$eb,$ff] then //possible
3003    begin
3004      case buf[0] of
3005        $0f:
3006        begin
3007          if (not (buf[1] in [$80..$8f])) then exit; //not one of them
3008          result:=true;
3009          addresstojumpto:=address+plongint(@buf[2])^+6;
3010        end;
3011
3012        $70..$7f,$e3,$eb:  //(un)conditional jump (1 byte)
3013        begin
3014          result:=true;
3015          addresstojumpto:=address+pshortint(@buf[1])^+2;
3016        end;
3017
3018        $e8,$e9: //jump or call unconditional (4 byte)
3019        begin
3020          result:=true;
3021          addresstojumpto:=address+plongint(@buf[1])^+5;
3022        end;
3023
3024        $ff: //disassemble to see what it is
3025        begin
3026          st:=disassemble(address);
3027          st:=copy(st,pos('-',st)+2,length(st));
3028          st:=copy(st,pos('-',st)+2,length(st));
3029
3030          i:=pos('jmp',st);
3031          j:=pos('call',st);
3032          if (i=1) or (j=1) then
3033          begin
3034            //now determine where it jumps to
3035            i:=pos('[',st);
3036            if i>0 then
3037            begin
3038              st:=copy(st,i,pos(']',st)-i+1);
3039
3040              addresstojumpto:=symhandler.getAddressFromName(st, false, haserror); //the pointer interpreter code can do this
3041              result:=not haserror;
3042            end;
3043
3044          end;
3045        end;
3046
3047
3048      end;
3049    end;
3050
3051  end;
3052{$endif}
3053
3054end;
3055
3056
3057function readAndParseAddress(address: dword; variableType: TVariableType): string;
3058var buf: array [0..7] of byte;
3059    x: dword;
3060    check: boolean;
3061begin
3062  result:='???';
3063  case variableType of
3064    vtByte:
3065    begin
3066      if ReadProcessMemory(processhandle,pointer(address),@buf[0],1,x) then
3067        result:=inttostr(buf[0]);
3068    end;
3069
3070    vtWord:
3071    begin
3072      if ReadProcessMemory(processhandle,pointer(address),@buf[0],2,x) then
3073        result:=inttostr(pword(@buf[0])^);
3074    end;
3075
3076    vtDWord:
3077    begin
3078      if ReadProcessMemory(processhandle,pointer(address),@buf[0],4,x) then
3079        result:=inttostr(pdword(@buf[0])^);
3080    end;
3081
3082    vtSingle:
3083    begin
3084      if ReadProcessMemory(processhandle,pointer(address),@buf[0],4,x) then
3085        result:=floattostr(psingle(@buf[0])^);
3086    end;
3087
3088    vtDouble:
3089    begin
3090      if ReadProcessMemory(processhandle,pointer(address),@buf[0],8,x) then
3091        result:=floattostr(pdouble(@buf[0])^);
3092    end;
3093  end;
3094end;
3095
3096const HEAP_NO_SERIALIZE               =$00000001;
3097const HEAP_GROWABLE                   =$00000002;
3098const HEAP_GENERATE_EXCEPTIONS        =$00000004;
3099const HEAP_ZERO_MEMORY                =$00000008;
3100const HEAP_REALLOC_IN_PLACE_ONLY      =$00000010;
3101const HEAP_TAIL_CHECKING_ENABLED      =$00000020;
3102const HEAP_FREE_CHECKING_ENABLED      =$00000040;
3103const HEAP_DISABLE_COALESCE_ON_FREE   =$00000080;
3104const HEAP_CREATE_ALIGN_16            =$00010000;
3105const HEAP_CREATE_ENABLE_TRACING      =$00020000;
3106const HEAP_CREATE_ENABLE_EXECUTE      =$00040000;
3107const HEAP_MAXIMUM_TAG                =$0FFF;
3108const HEAP_PSEUDO_TAG_FLAG            =$8000;
3109const HEAP_TAG_SHIFT                  =18;
3110
3111function heapflagstostring(heapflags: dword): string;
3112begin
3113  result:='';
3114  if (heapflags and HEAP_NO_SERIALIZE) > 0 then result:=result+'HEAP_NO_SERIALIZE+';
3115  if (heapflags and HEAP_GROWABLE) > 0 then result:=result+'HEAP_GROWABLE+';
3116  if (heapflags and HEAP_GENERATE_EXCEPTIONS) > 0 then result:='HEAP_GENERATE_EXCEPTIONS+';
3117  if (heapflags and HEAP_ZERO_MEMORY) > 0 then result:=result+'HEAP_ZERO_MEMORY+';
3118  if (heapflags and HEAP_REALLOC_IN_PLACE_ONLY) > 0 then result:=result+'HEAP_REALLOC_IN_PLACE_ONLY+';
3119  if (heapflags and HEAP_TAIL_CHECKING_ENABLED) > 0 then result:=result+'HEAP_TAIL_CHECKING_ENABLED+';
3120  if (heapflags and HEAP_FREE_CHECKING_ENABLED) > 0 then result:=result+'HEAP_FREE_CHECKING_ENABLED+';
3121  if (heapflags and HEAP_DISABLE_COALESCE_ON_FREE) > 0 then result:=result+'HEAP_DISABLE_COALESCE_ON_FREE+';
3122  if (heapflags and HEAP_CREATE_ALIGN_16) > 0 then result:=result+'HEAP_CREATE_ALIGN_16+';
3123  if (heapflags and HEAP_CREATE_ENABLE_TRACING) > 0 then result:=result+'HEAP_CREATE_ENABLE_TRACING+';
3124  if (heapflags and HEAP_CREATE_ENABLE_EXECUTE) > 0 then result:=result+'HEAP_CREATE_ENABLE_EXECUTE+';
3125  if (heapflags and HEAP_PSEUDO_TAG_FLAG) > 0 then result:=result+'HEAP_PSEUDO_TAG_FLAG+';
3126
3127
3128  if length(result)>0 then
3129    result:=Copy(result,1,length(result)-1)+'('+inttohex(heapflags,1)+')';
3130end;
3131
3132function allocationtypetostring(alloctype: dword): string;
3133begin
3134  result:='';
3135  if (alloctype and MEM_COMMIT) > 0 then result:='MEM_COMMIT+';
3136  if (alloctype and MEM_RESERVE) > 0 then result:=result+'MEM_RESERVE+';
3137  if (alloctype and MEM_RESET) > 0 then result:=result+'MEM_RESET+';
3138  if (alloctype and MEM_TOP_DOWN)       > 0 then result:=result+'MEM_TOP_DOWN+';
3139  if (alloctype and $400000) > 0 then result:=result+'MEM_PHYSICAL+';
3140  if (alloctype and $20000000) > 0 then result:=result+'MEM_LARGE_PAGES+';
3141
3142  if length(result)>0 then
3143    result:=Copy(result,1,length(result)-1)+'('+inttohex(alloctype,1)+')';
3144end;
3145
3146function allocationprotecttostring(protect: dword): string;
3147begin
3148  result:='';
3149  if (protect and PAGE_EXECUTE) > 0 then result:='PAGE_EXECUTE+';
3150  if (protect and PAGE_EXECUTE_READ) > 0 then result:=result+'PAGE_EXECUTE_READ+';
3151  if (protect and PAGE_EXECUTE_READWRITE) > 0 then result:=result+'PAGE_EXECUTE_READWRITE+';
3152  if (protect and PAGE_EXECUTE_WRITECOPY) > 0 then result:=result+'PAGE_EXECUTE_WRITECOPY+';
3153  if (protect and PAGE_NOACCESS) > 0 then result:=result+'PAGE_NOACCESS+';
3154  if (protect and PAGE_READONLY) > 0 then result:=result+'PAGE_READONLY+';
3155  if (protect and PAGE_READWRITE) > 0 then result:=result+'PAGE_READWRITE+';
3156  if (protect and PAGE_WRITECOPY) > 0 then result:=result+'PAGE_WRITECOPY+';
3157  if (protect and PAGE_GUARD) > 0 then result:=result+'PAGE_GUARD+';
3158  if (protect and PAGE_NOCACHE) > 0 then result:=result+'PAGE_NOCACHE+';
3159  if (protect and $400) > 0 then result:=result+'PAGE_WRITECOMBINE+';
3160
3161  if length(result)>0 then
3162    result:=Copy(result,1,length(result)-1)+'('+inttohex(protect,1)+')';
3163end;
3164
3165function freetypetostring(freetype: dword):string;
3166begin
3167  result:='';
3168 
3169  if (freetype and MEM_DECOMMIT) > 0 then result:='MEM_DECOMMIT+';
3170  if (freetype and MEM_RELEASE) > 0 then result:='MEM_RELEASE+'; 
3171  result:=Copy(result,1,length(result)-1)+'('+inttohex(freetype,1)+')';
3172end;
3173
3174
3175function isAddress(address: dword):boolean;
3176var mbi: TMemoryBasicInformation;
3177begin
3178  result:=false;
3179  if VirtualQueryEx(processhandle, pointer(address), mbi, sizeof(mbi))>0 then
3180    result:=(mbi.State=MEM_COMMIT);// and (mbi.AllocationProtect<>PAGE_NOACCESS);
3181end;
3182
3183
3184
3185initialization
3186  getmem(tempdir,256);
3187  GetTempPath(256,tempdir);
3188  GetWindir;
3189  keysfilemapping:=0;
3190  keys:=nil;
3191
3192  setlength(windowlist,0);
3193  setlength(donthidelist,0);
3194  allwindowsareback:=true;
3195  stealthhook:=0;
3196  iswin2kplus:=GetSystemType>=5;
3197
3198  flushthread:=TSaveDataThread.Create(false); //used for scanning, starts idled because the event isn't triggered
3199  prefetchthread:=TPrefetchDataThread.create(false);
3200
3201  processhandler:=TProcessHandler.create;
3202
3203finalization
3204  if flushthread<>nil then
3205  begin
3206    flushthread.Terminate;
3207    flushthread.dataavailable.SetEvent;
3208    flushthread.WaitFor;
3209    flushthread.free;
3210  end;
3211
3212  if tempdir<>nil then
3213    freemem(tempdir);
3214
3215end.
3216
3217
3218
Note: See TracBrowser for help on using the browser.