📄 cefuncproc.pas
字号:
((mbi.AllocationProtect and PAGE_EXECUTE_WRITECOPY)=PAGE_EXECUTE_WRITECOPY) then
begin
//executable
setlength(memoryregions,length(memoryregions)+1);
memoryregions[length(memoryregions)-1].BaseAddress:=dword(mbi.baseaddress);
memoryregions[length(memoryregions)-1].MemorySize:=mbi.RegionSize;
end;
inc(address,mbi.RegionSize);
end;
end;
{$ifndef standalonetrainer}
procedure FillMemoryProcess(start:dword;count:dword;fillvalue:byte);
var buf: array of byte;
original,actualwritten:dword;
begin
setlength(buf,count);
try
fillmemory(@buf[0],count,fillvalue);
rewritedata(processhandle,start,@buf[0],count);
finally
setlength(buf,0);
end;
end;
Procedure CreateCodeCave(address:dword; sourceaddress:dword; sizeofcave: integer);
var x,y: dword;
i:integer;
ignore,temp: string;
replacedopcodes: array of string;
jumpback: array [0..4] of byte;
reassembledinstruction:tassemblerbytes;
overwritesize: dword;
begin
x:=sourceaddress;
while x<(sourceaddress+5) do
begin
setlength(replacedopcodes,length(replacedopcodes)+1);
temp:=disassemble(x,ignore);
temp:=copy(temp,pos('-',temp)+1,length(temp));
temp:=copy(temp,pos('-',temp)+2,length(temp));
replacedopcodes[length(replacedopcodes)-1]:=temp;
end;
overwritesize:=x-sourceaddress;
x:=address+sizeofcave-5;
y:=x;
jumpback[0]:=$e9;
pdword(@jumpback[1])^:=sourceaddress-x;
virtualprotectex(processhandle,pointer(address),sizeofcave,PAGE_EXECUTE_READWRITE ,x);
fillmemoryprocess(address,sizeofcave,$90);
if sizeofcave>5 then
writeprocessmemory(processhandle,pointer(y),@jumpback[0],5,x);
x:=address;
for i:=0 to length(replacedopcodes)-1 do
begin
assemble(replacedopcodes[i],x,reassembledinstruction);
writeprocessmemory(processhandle,pointer(x),@reassembledinstruction[0],length(reassembledinstruction),y);
inc(x,length(reassembledinstruction));
end;
virtualprotectex(processhandle,pointer(sourceaddress),overwritesize,x,y);
//now place the jmp
setlength(reassembledinstruction,overwritesize);
reassembledinstruction[0]:=$e9;
pdword(@reassembledinstruction[1])^:=address-sourceaddress-5;
for i:=5 to overwritesize-1 do
reassembledinstruction[i]:=$90;
RewriteData(processhandle,sourceaddress,@reassembledinstruction[0],overwritesize);
end;
{$endif}
{$ifndef net}
procedure SetLanguage;
begin
{$ifdef DEU}if LoadNewResourceModule(LANG_GERMAN) <> 0 then ReinitializeForms{$endif}
{$ifdef RUS}if LoadNewResourceModule(LANG_RUSSIAN) <> 0 then ReinitializeForms{$endif}
{$ifdef NLD}if LoadNewResourceModule(LANG_DUTCH) <> 0 then ReinitializeForms{$endif}
end;
{$endif}
{$ifndef standalonetrainer}
{$ifndef net}
//Returns a random threadid owned by the target process
function getathreadid(processid:dword):dword;
var i: integer;
ths: thandle;
tE: threadentry32;
begin
if frmProcessWatcher<>nil then
begin
//first find a processid using the processwatcher
frmProcessWatcher.processesMREW.BeginRead;
try
for i:=0 to length(frmProcessWatcher.processes)-1 do
if frmProcessWatcher.processes[i].processid=processid then
begin
if length(frmProcessWatcher.processes[i].threadlist)>0 then
begin
result:=frmProcessWatcher.processes[i].threadlist[0].threadid;
exit;
end;
end;
finally
frmProcessWatcher.processesMREW.EndRead;
end;
end;
//no exit yet, so use a enumeration of all threads and this processid
ths:=CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);
if ths<>0 then
begin
te.dwSize:=sizeof(te);
if Thread32First(ths,te) then
begin
repeat
if te.th32OwnerProcessID=processid then
begin
result:=te.th32ThreadID;
closehandle(ths);
exit;
end;
until not thread32Next(ths,te);
end;
end;
closehandle(ths);
end;
{$endif}
procedure DetachIfPossible;
var crashcounter: integer;
waitform: TForm;
msg: tlabel;
begin
//detach the debugger
waitform:=nil;
crashcounter:=0;
{$ifndef net}
if debuggerthread=nil then exit else debuggerthread.Terminate;
if @DebugActiveProcessStop=@DebugActiveProcessStopProstitute then //lets help it a hand if it cant detach gracefully
terminateprocess(processhandle,0)
else
begin
if debuggerthread<>nil then
begin
//show a window asking the user to wait and not to freak out and think CE crashed!
waitform:=TForm.Create(nil);
with waitform do
begin
waitform.Caption:='Detaching...';
msg:=TLabel.Create(waitform);
msg.Caption:='Please wait while Cheat Engine tries to detach from the current process(This wont take longer than 30 seconds)';
waitform.Width:=msg.Width+20;
waitform.clientHeight:=50;
msg.Left:=7;
msg.Top:=(waitform.ClientHeight div 2) - (msg.Height div 2);
msg.Parent:=waitform;
//waitform.Parent:=self;
waitform.BorderStyle:=bsDialog;
waitform.BorderIcons:=[];
waitform.Position:=poScreenCenter;
waitform.Show;
waitform.Repaint;
end;
end;
end;
while (debuggerthread<>nil) and (debuggerthread.attached) and (crashcounter<30) do
begin
inc(crashcounter);
sleep(1000);
end;
if crashcounter=30 then messagedlg('Detaching failed!!! Your process is lost!',mtError,[mbok],0);
if waitform<>nil then
begin
waitform.Hide;
waitform.Free;
waitform:=nil;
end;
{$endif}
end;
{$endif}
Procedure InjectDll(dllname: string; functiontocall: string);
var LoadLibraryPtr: pointer;
GetProcAddressPtr: Pointer;
injectedlocation: pointer;
h: Thandle;
inject: array [0..4095] of byte;
x:dword;
outp:TAssemblerBytes;
position,position2: dword;
dllLocation: string;
startaddresS: dword;
functionloc: dword;
begin
h:=LoadLibrary('Kernel32.dll');
if h=0 then raise exception.Create('No kernel32.dll loaded');
try
GetProcAddressPtr:=GetProcAddress(h,'GetProcAddress');
if getprocaddressptr=nil then raise exception.Create('GetProcAddress not found');
LoadLibraryPtr:=GetProcAddress(h,'LoadLibraryA');
if LoadLibraryptr=nil then raise exception.Create('LoadLibraryA not found');
injectedlocation:=VirtualAllocEx(processhandle,nil,4096,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if injectedlocation=nil then raise exception.Create('Failed to allocate memory');
dlllocation:=dllname;
position:=dword(injectedlocation);
position2:=0;
copymemory(@inject[0],pchar(dllLocation+#0),length(dllLocation)+1);
inc(position,length(dllLocation)+1);
inc(position2,length(dllLocation)+1);
functionloc:=position;
copymemory(@inject[position2],pchar(functiontocall+#0),length(functiontocall)+1);
inc(position,length(functiontocall)+1);
inc(position2,length(functiontocall)+1);
startaddress:=position;
{ assemble('mov ['+inttohex(injectedlocation+4096-4,8)+'],esp');
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));}
assemble('PUSHFD',position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
assemble('PUSHAD',position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
//loadlibrary(cehook);
assemble('PUSH '+IntToHex(dword(injectedlocation),8),position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
assemble('CALL '+IntToHex(dword(LoadLibraryPtr),8),position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
if functiontocall<>'' then
begin
//getprocaddress
assemble('PUSH '+IntToHex(functionloc,8),position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
assemble('PUSH EAX',position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
assemble('CALL '+IntToHex(dword(GetProcAddressPtr),8),position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
//call function
assemble('CALL EAX',position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
end;
assemble('POPAD',position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
assemble('POPFD',position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
assemble('RET',position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
//call the routine
if not writeprocessmemory(processhandle,injectedlocation,@inject[0],position2,x) then raise exception.Create('Failed to inject the dll loader');
{$ifndef standalonetrainer}
{$ifndef net}
useapctoinjectdll:=false;
if useapctoinjectdll then
begin
showmessage('injected code at:'+inttohex(startaddress,8));
//suspend , message, resume is needed to prevent a crash when it is in a message loop
ntsuspendprocess(processid);
x:=getathreadid(processid);
PostThreadMessage(x,wm_paint,0,0);
CreateRemoteAPC(x,pointer(startaddress));
ntresumeprocess(processid);
end
else
{$endif}
{$endif}
if createremotethread(processhandle,nil,0,pointeR(startaddress),nil,0,x)=0 then raise exception.Create('Failed to execute the dll loader');
finally
FreeLibrary(h);
end;
end;
procedure EnableStealth;
var hookloc: pointer;
dll: thandle;
dllloc: string;
dllloc1: string;
dllloc2: string;
i: integer;
begin
if stealthhook>0 then exit;
createdir(cheatenginedir+'temp'); //in case it doesn't exist
dllloc1:=cheatenginedir+'temp\';
dllloc2:=cheatenginedir+'temp\';
//random sized name
for i:=1 to 3+random(6) do
dllloc1:=dllloc1+chr(64+random(26));
dllloc1:=dllloc1+'.DLL';
dllloc:=cheatenginedir+'stealth.dll';
if copyfile(pchar(dllloc),pchar(dllloc1),false) then
dll:=LoadLibrary(pchar(dllloc1))
else
dll:=loadlibrary(pchar(dllloc));
hookloc:=getprocaddress(dll,'hook');
hyperscanview.formscanningHandle:=setwindowshookex(WH_CALLWNDPROCRET ,hookloc,DLL,0); //just to get the dll inside the process
stealthhook:=hyperscanview.formscanningHandle;
end;
procedure DisableStealth;
var i: integer;
filedata:_WIN32_FIND_DATAA;
f: thandle;
filelist: array of string;
begin
if stealthhook<>0 then Unhookwindowshookex(stealthhook);
stealthhook:=0;
//delete tempdir
f:=FindFirstFile(pchar(cheatenginedir+'temp\*.DLL'),filedata);
if f<>invalid_handle_value then
begin
setlength(filelist,1);
filelist[length(filelist)-1]:=cheatenginedir+'temp\'+filedata.cFileName;
while findnextfile(f,filedata) do
begin
setlength(filelist,length(filelist)+1);
filelist[length(filelist)-1]:=cheatenginedir+'temp\'+filedata.cFileName;
end;
windows.FindClose(f);
end;
for i:=0 to length(filelist)-1 do
deletefile(filelist[i]);
setlength(filelist,0);
removedirectory(pchar(cheatenginedir+'temp'));
end;
procedure ToggleOtherWindows;
type Tprocesslistitem = record
processid: dword;
processname: string;
end;
var winhandle: Hwnd;
winprocess: Dword;
i,j: integer;
SNAPHandle: THandle;
ProcessEntry: ProcessEntry32;
Check: Boolean;
processlist: array of Tprocesslistitem;
hideall,hidethisone: boolean;
begin
hideall:=false;
allwindowsareback:=false;
if length(windowlist)<>0 then
begin
for i:=0 to length(windowlist)-1 do
showwindow(windowlist[i],SW_SHOW);
setlength(windowlist,0);
allwindowsareback:=true;
exit;
end;
lastactive:=getactivewindow;
lastforeground:=GetForegroundWindow;
if onlyfront then
begin
GetWindowThreadProcessId(lastforeground,addr(winprocess));
if getcurrentprocessid=winprocess then
begin
beep;
sleep(100);
beep;
sleep(100);
exit;
end;
setlength(windowlist,1);
windowlist[0]:=lastforeground;
showwindow(lastforeground,sw_hide);
exit;
end;
if length(donthidelist)>0 then
begin
//first get a process list
SNAPHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -