📄 cehook.dpr
字号:
library CEHook;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
SysUtils,
Classes,
windows,
Dialogs,
system,
math,
Messages,
graphics,
speedhack in 'speedhack.pas',
globals in 'globals.pas';
{$R *.res}
const donescanning=wm_user+1; //wparam=numberfound
ESScanningBool=wm_user+2; //wparam=address of scanning boolean. (should be the same in ce, but I like to verify it)
ESSettings=wm_user+3;
ESSetProgressbarMax=wm_user+4; //wparam=max
ESSetProgressbarPos=wm_user+5; //wparam=currentpos
HSThreadID=wm_user+6; //wparam=threadid
const
Exact_value = 0;
Increased_value = 1;
Increased_value_by = 2;
Decreased_value = 3;
Decreased_value_by = 4;
Changed_value = 5;
Unchanged_value = 6;
Advanced_Scan = 7;
String_Scan = 8;
SmallerThan = 9;
BiggerThan = 10;
Userdefined = 11;
valueBetween = 12;
Type TMemoryRegion = record
BaseAddress: Dword;
MemorySize: Dword;
IsChild: boolean;
end;
Type TBytes = array of integer;
type bitaddress = record
address: dword;
bit: dword;
end;
type TScanThread = class(TThread)
private
public
x: integer;
procedure Execute; override;
end;
type THyperscanWindow = class(TThread)
private
public
x: integer;
procedure Execute; override;
end;
//globals
var scanning: boolean;
CEScanWindow: THandle;
x: string;
bytes: array of integer; //-1=wildcard
bytearray: array of byte;
nrofbits: integer;
Bitscan: array of byte;
tempbits: array of byte;
bitoffsetchange: integer;
TotalToRead:dword;
buffersize: Dword;
AddressFile: File;
MemoryFile: File;
NewAddressFile: File;
NewMemoryFile: File;
MemoryRegion: array of TMemoryRegion;
MemoryRegions: Integer;
memory: ^byte;
FoundValue1:Array of Byte;
FoundValue2:Array of word;
FoundValue3:Array of Dword;
FoundValue4:Array of Single;
FoundValue5:Array of Double;
foundValue6:Array of int64; //byte ?????
FoundValue8:array of byte;
previousvalue1: array of Byte;
previousvalue2: array of word;
previousvalue3: array of dword;
previousvalue4: array of Single;
previousvalue5: array of Double;
previousvalue6: array of int64; //Byte;
FoundAddress,scanaddress: array of dword;
foundaddressB,scanaddressb: array of bitaddress;
lastscan:byte;
intercepttimermessages:boolean;
//speedhack
timeGetTimePos: pointer;
GetTickCountPos: pointer;
QueryPerformanceCounterpos: pointer;
winmmlib: thandle;
kernel32lib:thandle;
ST: TScanThread;
HTW: THyperscanwindow;
hyperscanwindowenabled: boolean;
procedure CopyMemory(Destination: Pointer; Source: Pointer; Length: DWORD); stdcall; external 'kernel32.dll' name 'RtlMoveMemory';
procedure freememory;
begin
now;
setlength(bitscan,0);
setlength(FoundValue1,0);
setlength(FoundValue2,0);
setlength(FoundValue3,0);
setlength(FoundValue4,0);
setlength(FoundValue5,0);
setlength(foundValue6,0);
setlength(FoundAddress,0);
setlength(foundaddressB,0);
setlength(previousvalue1,0);
setlength(previousvalue2,0);
setlength(previousvalue3,0);
setlength(previousvalue4,0);
setlength(previousvalue5,0);
setlength(previousvalue6,0);
setlength(scanaddress,0);
setlength(scanaddressb,0);
end;
procedure deletefiles;
begin
deletefile(pchar(scansettings^.CheatEngineDir+'Addresses.TMP'));
deletefile(pchar(scansettings^.CheatEngineDir+'Memory.TMP'));
deletefile(pchar(scansettings^.CheatEngineDir+'Addresses2.TMP'));
deletefile(pchar(scansettings^.CheatEngineDir+'Memory2.TMP'));
end;
procedure closefiles;
begin
try
closefile(addressfile);
closefile(memoryfile);
closefile(newAddressfile);
closefile(newmemoryfile);
except
end;
end;
procedure ConvertStringToBytes(scanvalue:string; hex:boolean;var bytes: TBytes);
var i,j,k: integer;
helpstr:string;
begin
while scanvalue[length(scanvalue)]=' ' do
scanvalue:=copy(scanvalue,1,length(scanvalue)-1);
if (pos('-',scanvalue)>0) or (pos(' ',scanvalue)>0) then
begin
//syntax is xx-xx-xx or xx xx xx
j:=1;
k:=0;
scanvalue:=scanvalue+' ';
for i:=1 to length(scanvalue) do
begin
if (scanvalue[i]=' ') or (scanvalue[i]='-') then
begin
helpstr:=copy(scanvalue,j,i-j);
j:=i+1;
setlength(bytes,k+1);
try
if hex then bytes[k]:=strtoint('$'+helpstr)
else bytes[k]:=strtoint(helpstr);
except
bytes[k]:=-1;
//if it is not a '-' or ' ' or a valid value then I assume it is a wildcard.(
end;
inc(k);
end;
end;
end else
begin
//syntax is xxxxxx
k:=0;
j:=1;
for i:=1 to length(scanvalue) do
begin
if (i mod 2)=0 then
begin
helpstr:=copy(scanvalue,j,i-j+1);
j:=i+1;
setlength(bytes,k+1);
try
bytes[k]:=strtoint('$'+helpstr);
except
bytes[k]:=-1;
end;
inc(k);
end;
end;
end;
end;
function getbit(bitnr: integer; bt: Byte):integer;
begin
if (trunc(power(2,bitnr)) and bt)>0 then result:=1 else result:=0;
end;
function scanbits(var found: dword;number:dword;var bytep: pbyte;nrofbits,i,actualread: integer): boolean;
var j,k,l,m: integer;
actualwrite: dword;
tempcount: integer;
tempj,tempk: integer;
tempb: pbyte;
begin
for j:=0 to actualread-1 do
begin
//scan each bit till you find bitarray[bittofind]
for k:=0 to 7 do
begin
tempb:=bytep;
//see if there are enough bits to scan, if not, save the bits to be scanned and exit
//bitsleft=((actualread-j)*8) - k
if nrofbits>(((actualread-j)*8) - k) then
begin
tempcount:=(((actualread-j)*8) - k); //should always be nrofbits-1
setlength(tempbits,nrofbits);
tempk:=k;
for l:=1 to tempcount do
begin
tempbits[l]:=getbit(tempk,bytep^);
inc(tempk);
if tempk>7 then
begin
inc(bytep);
tempk:=0;
end;
end;
result:=true;
exit;
end;
m:=k;
for l:=0 to nrofbits-1 do
begin
if bitscan[l]<>2 then
if getbit(m,tempb^)<>bitscan[l] then break;
if l=nrofbits-1 then
begin
//foundit
foundaddressb[found].address:=memoryregion[i].BaseAddress+j;
foundaddressb[found].bit:=k;
inc(found);
if found=number then
begin
blockwrite(Addressfile,pointer(foundaddressB)^,found*(sizeof(bitaddress)),actualwrite);
found:=0;
end;
end;
inc(m);
if m>7 then
begin
m:=0;
inc(tempb);
end;
end;
end;
inc(bytep);
end;
result:=true;
end;
function RemoveRangewith(address: dword):boolean;
var i,j: integer;
begin
result:=false;
for i:=0 to memoryregions-1 do //still -1 here
begin
if (address>=(memoryregion[i].BaseAddress)) and
(address<(memoryregion[i].BaseAddress+memoryregion[i].MemorySize)) then
begin
//remove it
for j:=i to memoryregions-2 do
memoryregion[j]:=memoryregion[j+1];
dec(memoryregions);
setlength(memoryregion,length(memoryregion)-1);
result:=true;
exit;
end;
end;
end;
procedure GetMemoryRanges(const exclude: array of dword);
var address: Dword;
mbi : _MEMORY_BASIC_INFORMATION;
i: Integer;
j: dword;
size: dword;
skip: boolean;
dlladdr: dword;
temp: dword;
label x;
begin
buffersize:=scansettings^.buffersize;
address:=scansettings^.StartAddress;
memoryregions:=0;
setlength(memoryregion,0);
try
outputdebugstring('GetMemoryRanges');
while (Virtualquery(pointer(address),mbi,sizeof(mbi))<>0) and (address<scansettings^.stopaddress) do
begin
skip:=false;
for i:=0 to length(exclude)-1 do
begin
if (exclude[i]>=dword(mbi.BaseAddress)) and
(exclude[i]<(dword(mbi.BaseAddress)+mbi.RegionSize)) then
begin
skip:=true;
break;
end;
end;
if skip then
begin
address:=dword(mbi.baseaddress)+mbi.RegionSize;
continue;
end;
if (not (not scansettings^.scan_mem_private and (mbi.type_9=mem_private))) and (not (not scansettings^.scan_mem_image and (mbi.type_9=mem_image))) and (not (not scansettings^.scan_mem_mapped and (mbi.type_9=mem_mapped))) and (mbi.State=mem_commit) and ((mbi.Protect and page_guard)=0) and ((mbi.protect and page_noaccess)=0) then //look if it is commited
begin
if not scansettings^.readonly then //if the settings are set to not read read-only memory then
begin
if (((mbi.AllocationProtect) and (page_readonly or page_execute_read))=0) and
(((mbi.Protect) and (page_readonly or PAGE_EXECUTE_READ))=0) then //look if the memory is not read-only , if 0 it means it's not read-only
begin
if scansettings^.Skip_PAGE_NOCACHE then
if (mbi.AllocationProtect and PAGE_NOCACHE)=PAGE_NOCACHE then
begin
address:=dword(mbi.BaseAddress)+mbi.RegionSize;
continue;
end;
setlength(memoryregion,memoryregions+1);
memoryregion[memoryregions].BaseAddress:=dword(mbi.baseaddress); //remember if it's not read only
memoryregion[memoryregions].MemorySize:=mbi.RegionSize;
inc(memoryregions);
end;
end else //if the settings are to also read the read only then:
begin
if scansettings^.Skip_PAGE_NOCACHE then
if (mbi.AllocationProtect and PAGE_NOCACHE)=PAGE_NOCACHE then
begin
address:=dword(mbi.BaseAddress)+mbi.RegionSize;
continue;
end;
setlength(memoryregion,memoryregions+1);
memoryregion[memoryregions].BaseAddress:=dword(mbi.baseaddress); //just remember this location
memoryregion[memoryregions].MemorySize:=mbi.RegionSize;
inc(memoryregions);
end;
end;
address:=dword(mbi.baseaddress)+mbi.RegionSize;
end;
if memoryregions=0 then raise exception.Create('No memory found');
if (memoryregion[0].BaseAddress<scansettings^.StartAddress) and (memoryregion[0].MemorySize-(scansettings^.StartAddress-memoryregion[0].BaseAddress)>0) then
begin
memoryregion[0].MemorySize:=memoryregion[0].MemorySize-(scansettings^.StartAddress-memoryregion[0].BaseAddress);
memoryregion[0].BaseAddress:=scansettings^.StartAddress;
end;
if (memoryregion[memoryregions-1].BaseAddress+memoryregion[memoryregions-1].MemorySize)>scansettings^.StopAddress then
dec(memoryregion[memoryregions-1].MemorySize,(memoryregion[memoryregions-1].BaseAddress+memoryregion[memoryregions-1].MemorySize)-scansettings^.StopAddress-1);
RemoveRangewith(dword(@scansettings));
RemoveRangeWith(dword(@scansettings.scanning));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -