📄 cefuncproc.pas.svn-base
字号:
VK_F4 : newstr:='F4';
VK_F5 : newstr:='F5';
VK_F6 : newstr:='F6';
VK_F7 : newstr:='F7';
VK_F8 : newstr:='F8';
VK_F9 : newstr:='F9';
VK_F10 : newstr:='F10';
VK_F11 : newstr:='F11';
VK_F12 : newstr:='F12';
VK_F13 : newstr:='F13';
VK_F14 : newstr:='F14';
VK_F15 : newstr:='F15';
VK_F16 : newstr:='F16';
VK_F17 : newstr:='F17';
VK_F18 : newstr:='F18';
VK_F19 : newstr:='F19';
VK_F20 : newstr:='F20';
VK_F21 : newstr:='F21';
VK_F22 : newstr:='F22';
VK_F23 : newstr:='F23';
VK_F24 : newstr:='F24';
VK_NUMLOCK : newstr:='Num Lock';
VK_SCROLL : newstr:='Scroll Lock';
48..57 : newstr:=chr(x[i]);
65..90 : newstr:=chr(x[i]);
else newstr:='#'+inttostr(x[i]);
end;
result:=result+newstr+'+';
end;
result:=copy(result,1,length(result)-1);
end;
procedure getexecutablememoryregionsfromregion(start: dword; stop:dword; var memoryregions: tmemoryregions);
var address: dword;
mbi: memory_basic_information;
begin
setlength(memoryregions,0);
address:=start;
while (address<stop) and (VirtualQueryEx(processhandle,pointer(address),mbi,sizeof(mbi))<>0) and ((address+mbi.RegionSize)>address) do
begin
if ((mbi.AllocationProtect and PAGE_EXECUTE)=PAGE_EXECUTE) or
((mbi.AllocationProtect and PAGE_EXECUTE_READ)=PAGE_EXECUTE_READ) or
((mbi.AllocationProtect and PAGE_EXECUTE_READWRITE)=PAGE_EXECUTE_READWRITE) or
((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;
if debuggerthread2<>nil then
begin
debuggerthread2.Terminate;
debuggerthread2.WaitFor;
end;
{$endif}
end;
{$endif}
Procedure InjectDll(dllname: string; functiontocall: string);
var LoadLibraryPtr: pointer;
GetProcAddressPtr: Pointer;
h: Thandle;
inject: array [0..4095] of byte;
x:dword;
outp:TAssemblerBytes;
position,position2: dword;
dllLocation: string;
startaddresS: dword;
functionloc: dword;
injectionlocation: pointer;
threadhandle: thandle;
begin
h:=LoadLibrary('Kernel32.dll');
if h=0 then raise exception.Create('No kernel32.dll loaded');
injectionlocation:=nil;
try
try
getprocaddressptr:=pointer(symhandler.getAddressFromName('GetProcAddress',true));
except
GetProcAddressPtr:=GetProcAddress(h,'GetProcAddress');
end;
if getprocaddressptr=nil then raise exception.Create('GetProcAddress not found');
try
LoadLibraryPtr:=pointer(symhandler.getAddressFromName('LoadLibraryA',true));
except
//failed getting the address of LoadLibraryA, use old method
LoadLibraryPtr:=GetProcAddress(h,'LoadLibraryA');
end;
if LoadLibraryptr=nil then raise exception.Create('LoadLibraryA not found');
injectionlocation:=VirtualAllocEx(processhandle,nil,4096,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if injectionlocation=nil then raise exception.Create('Failed to allocate memory');
dlllocation:=dllname;
position:=dword(injectionlocation);
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;
//loadlibrary(cehook);
assemble('PUSH '+IntToHex(dword(injectionlocation),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));
//safetycode, test if the dll was actually loaded and scip if not
assemble('TEST EAX,EAX',position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
assemble('JNE '+inttohex(position+3+5,8),position,outp); //jump over the ret
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
assemble('MOV EAX,2',position,outp); //exitcode=2
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));
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));
assemble('TEST EAX,EAX',position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
assemble('JNE '+inttohex(position+3+5,8),position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
assemble('MOV EAX,3',position,outp); //exitcode=3
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 function
assemble('CALL EAX',position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
end;
assemble('MOV EAX,1',position,outp); //causes the exitcode of the thread be 1
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,injectionlocation,@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}
begin
threadhandle:=createremotethread(processhandle,nil,0,pointer(startaddress),nil,0,x);
if threadhandle=0 then raise exception.Create('Failed to execute the dll loader');
if waitforsingleobject(threadhandle,10000)=WAIT_TIMEOUT then //max 10 seconds
raise exception.Create('The injection thread took longer than 10 seconds to execute. Injection routine not freed');
if getexitcodethread(threadhandle,x) then
begin
case x of
1: ;//success
2: raise exception.Create('Failed injecting the DLL');
3: raise exception.Create('Failed executing the function of the dll');
else raise exception.Create('Unknown error during injection');
end;
end; //else unsure, did it work or not , or is it crashing?
end;
finally
FreeLibrary(h);
if injectionlocation<>nil then
virtualfreeex(processhandle,injectionlocation,0,MEM_RELEASE );
end;
end;
procedure EnableStealth;
var hookloc: pointer;
dll: thandle;
dllloc: string;
dllloc1: string;
dllloc2: string;
i: integer;
begin
if stealthhook>0 then exit;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -