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

📄 debugger.pas

📁 冒险岛吸怪源码UCE的制作材料 用于冒险岛游戏的外挂
💻 PAS
📖 第 1 页 / 共 5 页
字号:
                break;
              end;


            setbreakpoints;
            releasesemaphore(semaphore,1,nil);
            result:=false;
            exit;
          end;


        if length(userbreakpoints)=3 then
          raise exception.Create('The current implementation doesn''t support more than 3 breakpoints. (4 debug registers, but 1 is needed for stepping-over code)');

        setlength(userbreakpoints,length(userbreakpoints)+1);
        userbreakpoints[length(userbreakpoints)-1]:=address;

        setbreakpoints;
        result:=true;
      end
      else
      begin
        //int3 breakpoints
        //find it in the breakpointlist
        for i:=0 to length(int3userbreakpoints)-1 do
        begin
          if int3userbreakpoints[i].address=address then
          begin
            //remove it
            RewriteCode(processhandle,address,@int3userbreakpoints[i].originalbyte,1);

            for j:=i to length(int3userbreakpoints)-2 do
            begin
              int3userbreakpoints[j].address:=int3userbreakpoints[j+1].address;
              int3userbreakpoints[j].originalbyte:=int3userbreakpoints[j+1].originalbyte;
            end;

            setlength(int3userbreakpoints,length(int3userbreakpoints)-1);
            result:=false;
            exit;
          end;
        end;

        //no, it's not in the list, so ADD:
        setlength(int3userbreakpoints,length(int3userbreakpoints)+1);
        int3userbreakpoints[length(int3userbreakpoints)-1].address:=address;

        readprocessmemory(processhandle,pointer(address),@int3userbreakpoints[length(int3userbreakpoints)-1].originalbyte,1,a);
        if a=1 then
          RewriteCode(processhandle,address,@int3,1)
        else
          setlength(int3userbreakpoints,length(int3userbreakpoints)-1);

        result:=true;
      end;
    finally
      memorybrowser.updatebplist;
      releasesemaphore(semaphore,1,nil);
    end;
  end;

  {$endif}
end;

procedure RemoveDebuggerDetection(processhandle: thandle);
var Newfunction: array [0..2] of byte;
    original,written: dword;
begin
  if IsDebuggerPresentLocation=0 then exit;
  {
    xor eax,eax
    ret
  }
  Newfunction[0]:=$31;
  NewFunction[1]:=$c0;
  NewFunction[2]:=$c3;

  RewriteCode(processhandle,IsDebuggerPresentLocation,@newfunction[0],3);
end;

function DebugBreakProstitute(x: Thandle):boolean;
begin
  result:=false;
end;

function DebugSetProcessKillOnExitProtitute(x: boolean):boolean;
begin
  result:=false;
end;

function DebugActiveProcessStopProstitute(x: dword): boolean;
begin
  result:=false;
end;

function startdebuggerifneeded(ask:boolean): boolean; overload;
var mes: string;
    reS:boolean;
    i: integer;
begin
  result:=false;
  if processhandle=0 then raise exception.create('You must first open a process');

  {$ifndef netserver}
  if debuggerthread2<>nil then
  begin
    if messagedlg('The kerneldebugger is currently active. Enabling the default windows debugger will cause the kernel debugger to terminate itself. Continue?',mtwarning,[mbyes,mbno],0)=mrno then exit;
    freeandnil(debuggerthread2);
  end;
  {$endif}

  if (debuggerthread=nil) or (not debuggerthread.attached) then
  begin
    if @DebugActiveProcessStop=@DebugActiveProcessStopProstitute then
      mes:='This will attach the debugger of Cheat Engine to the current process. If you close Cheat Engine while the game is running, the game will close too. Are you sure you want to do this?'
    else
      mes:='This will attach the debugger of Cheat Engine to the current process. Continue?';

    {$ifndef net}
    if ask then
      res:=Messagedlg(mes,mtConfirmation,[mbYes, mbNo],0)=mrYes
    else
      res:=true;

    if res then
    {$endif}
    begin
      {$ifndef net}
      if not advancedoptions.Pausebutton.Down then
        @ntsuspendprocess:=nil; //lets use the debugger for this
      {$endif}

      //start the debugger on the current process
      //check for a debugger
      Debuggerthread:=TDebugger.MyCreate2(processid);
      while (debuggerthread<>nil) and DebuggerThread.attaching do sleep(10);  //give him some time
      if not debuggerthread.attached then
      begin
        debuggerthread.Free;
        debuggerthread:=nil;
        raise exception.Create('I couldn''t attach the debugger to this process! You could try to open the process using the processpicker and try that! If that also doesn''t work check if you have debugging rights.');
      end;

      {$ifndef netserver}
      //Enable the debugger screen for the memorybrowser
      memorybrowser.splitter1.Visible:=true;
      memorybrowser.panel1.Visible:=true;

      memorybrowser.view1.Visible:=true;
      memorybrowser.Debug1.Visible:=true;
      memorybrowser.Splitter2.Visible:=true;
      memorybrowser.RegisterView.Visible:=true;

      Memorybrowser.UpdateRegisterview;
      {$endif}

      result:=true;
      exit;
    end
    {$ifndef net}
    else
    begin
      result:=false;
      exit;
    end;
    {$endif}
  end;
  result:=true;
end;

function startdebuggerifneeded: boolean;  overload;
begin
  result:=startdebuggerifneeded(true);
end;

function Breakthread(threadhandle:thandle):boolean;
var c: _context;
begin
  if GetSystemType<3 then raise exception.Create('You can''t break on this OS. Windows ME or later is required. (You CAN set breakpoints at key locations)');

  zeromemory(@c,sizeof(c));

  c.ContextFlags:=CONTEXT_FULL or CONTEXT_FLOATING_POINT or CONTEXT_DEBUG_REGISTERS;

  debuggerthread.suspend;
  suspendthread(threadhandle);
  if not getthreadcontext(threadhandle,c) then exit;

  debuggerthread.userisdebugging:=true;

  with debuggerthread do
  begin
    DRRegs.ContextFlags:=CONTEXT_DEBUG_REGISTERS;
    DRRegs.Dr7:=reg0set or reg1set or reg2set or reg3set;
    DRRegs.Dr0:=0;
    drregs.dr1:=0;
    drregs.dr2:=0;
    DRRegs.Dr3:=c.Eip;
    if setthreadcontext(threadhandle,drregs) then result:=true;
  end;


  resumethread(threadhandle);
  debuggerthread.Resume;
end;


Constructor TDebugger.MyCreate(filenm: String);
begin
  {$ifndef netserver}
  if debuggerthread2<>nil then raise exception.Create('Please stop the kernelmode debugging routines and breakpoints before starting this debugger');

  if formsettings.cbUndoMemoryChanges.checked then CheckForChanges; //place this line at important places

  if formsettings.cbBreakOnAttach.checked and (ProcessWindow<>nil) then    //created using the process list
    createdusingprocesswindow:=true;
  {$endif}

  userisdebugging:=false;
  {$ifndef netserver}
  handlebreakpoints:=formsettings.CheckBox1.Checked;
  hidedebugger:=formsettings.checkbox1.checked;
  canusedebugregs:=formsettings.rbDebugAsBreakpoint.checked;
  formdebugstrings.listbox1.clear;
  {$endif}
    
  attaching:=true;
  filename:=filenm;
  Inputquery(filename,'Parameters:',parameters);

  debugging:=true;
  processhandle:=2;
  howtocontinue:=0;
  createAprocess:=true;
  inherited Create(false);   //I know, I know, these initalizes could also be done in the execute part.
end;

Constructor TDebugger.MyCreate2(processID: THandle);
var
  debugportoffset:dword;
  debugport:dword;
  ar:dword;
  peprocess: dword;
begin

  {$ifndef netserver}
  if debuggerthread2<>nil then
  begin
    if messagedlg('The kerneldebugger is currently active. Enabling the default windows debugger will cause the kernel debugger to terminate itself. Continue?',mtwarning,[mbyes,mbno],0)=mrno then exit;
    freeandnil(debuggerthread2);
  end;
  
  if formsettings.cbUndoMemoryChanges.checked then CheckForChanges; //place this line at important places

  if formsettings.cbBreakOnAttach.checked and (ProcessWindow<>nil) then    //created using the process list
    createdusingprocesswindow:=true;
  {$endif}

  userisdebugging:=false;

  {$ifndef netserver}
  handlebreakpoints:=formsettings.cbHandleBreakpoints.checked;
  hidedebugger:=formsettings.checkbox1.checked;
  canusedebugregs:=formsettings.rbDebugAsBreakpoint.checked;
  formdebugstrings.listbox1.clear;
  {$endif}

  attaching:=true;
  debugging:=true;
  howtocontinue:=0;
  createAprocess:=false;
  OpenprocessID:=processid;

  processhandle:=OpenProcess(process_all_access,false,processid);

  {$ifndef net}
  //check for a debugger

  if (getsystemtype>5) and (formsettings.cbKernelOpenProcess.Checked) then
  begin
    debugportoffset:=GetDebugportOffset;

    if debugportoffset<>0 then
    begin
      peprocess:=getpeprocess(processid);
      if peprocess<>0 then
      begin
        debugport:=0;
        if KernelReadProcessMemory(processhandle,pointer(peprocess+debugportoffset),@debugport,4,ar) then
        begin
          //readable
          if (debugport<>0) and
             (messagedlg('There is already a debugger attached to this process. Do you want to override it ? (Only works in winxp+)',mtconfirmation,[mbyes,mbno],0)=mryes) then
          begin
            debugport:=0;
            KernelWriteProcessMemory(processhandle,pointer(peprocess+debugportoffset),@debugport,4,ar);
            //debugger gone
          end;
        end;
      end;
    end; //else no way to check or fix it
  end;

  {$endif}
  inherited Create(false);   //I know, I know, these initalizes could also be done in the execute part.
end;

destructor TDebugger.Destroy;
begin
  inherited Destroy;
end;


procedure TDebugger.RestoreNTOpenProcess;
var NTOpenProcessPos: dword;
    MyNTOpenProcessPos: dword;
    x: dword;
    y: array [0..4] of byte;
    mykernel: thandle;
begin
  NTOpenProcessPos:=dword(getprocaddress(ntdlllib,'NtOpenProcess'));

  LoadDbk32;
  if GetLoadedState then
  begin
    MyNTOpenProcessPos:=dword(getprocaddress(DarkByteKernel,'NOP'));

    If MyNTOpenProcessPos<>0 then
    begin
      if VirtualProtect(pointer(NTOpenProcessPos-50),55,PAGE_EXECUTE_READWRITE,x) then
      begin
        y[0]:=$e9;
        pdword(@y[1])^:=MyNTOpenProcessPos-NTOpenProcessPos-5;

        try
          asm
            push edi
            push esi
            lea esi,y[0]
            mov edi,NTOpenProcessPos
            movsd
            movsb
            pop esi
            pop edi
          end;
        except

        end;
      end;
    end;
  end;
end;


procedure TDebugger.AddDebugString;
begin
  {$ifndef netserver}
  formdebugstrings.listbox1.Items.add(temps);
  {$endif}
end;

procedure TDebugger.addtochangeslist;
begin
  {$ifndef netserver}
  with memorybrowser do
  begin
    EAXv:=context.Eax;
    EBXv:=context.Ebx;
    ECXv:=context.Ecx;
    EDXv:=context.Edx;
    ESIv:=context.Esi;
    EDIv:=context.Edi;
    EBPv:=context.Ebp;
    ESPv:=context.Esp;
    EIPv:=context.Eip;
  end;

  try
    lastbreakpoint:=getaddress(temps);
  except
    //
  end;
  if frmchangedaddresses.Changedlist.Items.IndexOf(inttohex(lastbreakpoint,8))=-1 then
    frmchangedaddresses.Changedlist.Items.Add(inttohex(lastbreakpoint,8));
  {$endif}
end;

procedure TDebugger.debuginfo;
begin

end;

procedure TDebugger.ProcessCreated;
begin
  {$ifndef netserver}
  if frmCreatedProcessList=nil then
  begin
    frmCreatedProcesslist:=tfrmcreatedprocesslist.create(nil);
    frmCreatedProcesslist.show;
  end;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -