⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cefuncproc.pas.svn-base

📁 这是一段游戏修改工具的源代码.ring3功能由dephi开发,驱动是C开发.希望对大家有帮助
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
        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 + -