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

📄 debugger.pas.svn-base

📁 这是一段游戏修改工具的源代码.ring3功能由dephi开发,驱动是C开发.希望对大家有帮助
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
unit Debugger;
//just my place to play with all kinds of threading methods
//when i find out the best suited method I'll use that....

interface

uses Classes,windows,sysutils,cefuncproc,Messages,forms,SyncObjs,
     dialogs,controls,Graphics,NewKernelHandler,symbolhandler,StrUtils
     {$ifndef net}
     ,undochanges,assemblerunit,addressparser  //handled in the client version or not at all
     {$endif}
     {$ifdef netserver}      
     ,unit1
     ,idtcpserver
     {$endif};

const reg0set= $3;          //(00000000000000000000000000000011)
      reg1set= $C;          //(00000000000000000000000000001100)
      reg2set= $30;         //(00000000000000000000000000110000)
      reg3set= $c0;         //(00000000000000000000000011000000)
                                               


      debugexact= $300;
      gd_flag= $2000;       //(00000000000000000010000000000000)
      reg0w=   $10000;      //(00000000000000010000000000000000)
      reg0rw=  $30000;      //(00000000000000110000000000000000)
      reg0len2=$40000;      //(00000000000001000000000000000000)
      reg0len4=$c0000;      //(00000000000011000000000000000000)
      reg1w=   $100000;     //(00000000000100000000000000000000)
      reg1rw=  $300000;     //(00000000001100000000000000000000)
      reg1len2=$400000;     //(00000000010000000000000000000000)
      reg1len4=$c00000;     //(00000000110000000000000000000000)
      reg2w=   $1000000;    //(00000001000000000000000000000000)
      reg2rw=  $3000000;    //(00000011000000000000000000000000)
      reg2len2=$4000000;    //(00000100000000000000000000000000)
      reg2len4=$c000000;    //(00001100000000000000000000000000)
      reg3w=   $10000000;   //(00010000000000000000000000000000)
      reg3rw=  $30000000;   //(00110000000000000000000000000000)
      reg3len2=$40000000;   //(01000000000000000000000000000000)
      reg3len4=$c0000000;   //(11000000000000000000000000000000)
      reg0len0=0;
      reg1len0=0;
      reg2len0=0;
      reg3len0=0;

type TReadonly = record
  pagebase: dword;
  pagesize: dword;
  Address: dword;
  size: integer;
  originalprotection:  dword;
end;

type tThreadEntry=record
  threadHandle: thandle;
  address: dword;
end;


type Process=record
  ProcessID: dword;
  running: boolean;
end;

type tbreakpoint = record
  address:dword;
  originalbyte: byte;
end;

type tregistermodificationBP=record
  address:dword; //addres to break on
  change_eax:boolean;
  change_ebx:boolean;
  change_ecx:boolean;
  change_edx:boolean;
  change_esi:boolean;
  change_edi:boolean;
  change_ebp:boolean;
  change_esp:boolean;
  change_eip:boolean;
  change_cf:boolean;
  change_pf:boolean;
  change_af:boolean;
  change_zf:boolean;
  change_sf:boolean;
  change_of:boolean;
  new_eax:dword;
  new_ebx:dword;
  new_ecx:dword;
  new_edx:dword;
  new_esi:dword;
  new_edi:dword;
  new_ebp:dword;
  new_esp:dword;
  new_eip:dword;
  new_cf:boolean;
  new_pf:boolean;
  new_af:boolean;
  new_zf:boolean;
  new_sf:boolean;
  new_of:boolean;
end;
type PRegisterModificationBP=^TRegisterModificationBP;

type TNewProcedureData=record
  processid: dword;
  processhandle: dword;
  filehandle: dword;
  EntryPoint: dword;
  OriginalEntryByte: byte;
  DotNet: boolean;
  FirstBreak: boolean;
end;


type TDebugger = class(TThread)
  private
    originalbyte: byte;
    filename: String;
    parameters: string;
    CreateAProcess: boolean;
    OpenProcessID: Thandle;

    AddressFound: Dword;
    HideDebugger: boolean;
    HandleBreakpoints: boolean;

    CanUseDebugRegs: boolean;
    createdusingprocesswindow:boolean;

    CurrentProcess: integer;


    {$ifdef netserver}
    coderecords: array of dword;
    {$endif}

    procedure addtochangeslist;
    procedure ProcessCreated;

    procedure RestoreNTOpenProcess;

    procedure ResetBreakpoint;
    procedure SetSingleStepping(Threadid: dword);
    procedure AddDebugString;
    function injectcode(AddressOfEntryPoint:dword;processhandle:thandle):dword;
    function handledebuggerplugins(devent:PDebugEvent):integer;

    procedure tracersync;
    function tracer(devent: _Debug_EVENT):boolean;

  public
    //semaphore: THandle;
    Processes: array of process;
    Newprocesses: array of TNewProcedureData;


    pausedthreadhandle: thandle;

    running: boolean;
    continueprocess: boolean;
    continuehow: integer;

    DRRegs: _CONTEXT;

    FindWriter2: boolean;


    attaching: boolean;
    attached: boolean;
    context: _CONTEXT;
    debugging: boolean;
    stepping: boolean;
    HowToContinue: integer;
    removed: boolean;

    readonly: TReadonly;
    readonlyset: boolean;
    readonlyremoved: boolean;

    findreaderset: boolean;
    findreader: TReadOnly;
    findreaderremoved:boolean;

    alsowrites: boolean;

    breakpointset: boolean;
    breakpointaddress: dword;
    lastbreakpoint: dword;
    temps: string;

    whattodo: integer; //ignore, continue, showwindow etc....

    userisdebugging: boolean;
    userbreakpoints: array of dword;
    registermodificationBPs: array of tregistermodificationBP;

    int3userbreakpoints: array of tbreakpoint;
    int3CEBreakpoint: TBreakpoint;

    threadlist: array of array [0..4] of dword;
    threadinfo: array of dword;


    testje: string;

    breakpointlistsection: TCriticalSection;
    threadentrys: array of tThreadEntry;

    traceaddress: dword;
    tracecount: integer;
    Constructor MyCreate(filenm: String);
    Constructor MyCreate2(processID: THandle);
    destructor Destroy; override;
    procedure Execute; override;
    procedure Debuginfo;

    procedure Updateregisters;
    procedure FoundOne;
    procedure RemoveBreakpoint;

    procedure suspendallthreads;
    procedure resumeallthreads;

  end;


type TDbgUIDebugActiveProcess = function(processhandle:THandle):boolean; stdcall;
type TDebugBreakProcess = function(processhandle:THandle):boolean; stdcall;
type TDebugActiveProcessStop= function(pid: dword):boolean; stdcall;
type TDebugSetProcessKillOnExit=function(KillOnExit: boolean):boolean; stdcall;
type TIsDebuggerPresent=function:boolean; stdcall;
type TntSuspendProcess=function(ProcessID:Dword):DWORD; stdcall;
type TntResumeProcess=function(ProcessID:Dword):DWORD; stdcall;




type
TProcessBasicInformation = record
ExitStatus : Longint;
PebBaseAddress : Pointer;
AffinityMask : DWORD;
BasePriority : Longint;
UniqueProcessId : DWORD;
InheritedFromUniqueProcessId : DWORD
end;


  TProcessInfoClass=(
  ProcessBasicInformation,ProcessQuotaLimits,ProcessIoCounters,ProcessVmCounters,ProcessTimes,
  ProcessBasePriority,ProcessRaisePriority,ProcessDebugPort,ProcessExceptionPort,ProcessAccessToken,
  ProcessLdtInformation,ProcessLdtSize,ProcessDefaultHardErrorMode,ProcessIoPortHandlers,
  ProcessPooledUsageAndLimits,ProcessWorkingSetWatch,ProcessUserModeIOPL,ProcessEnableAlignmentFaultFixup,
  ProcessPriorityClass,ProcessWx86Information,ProcessHandleCount,ProcessAffinityMask,ProcessPriorityBoost,
  ProcessDeviceMap,ProcessSessionInformation,ProcessForegroundInformation,ProcessWow64Information,
  MaxProcessInfoClass);
type TNtQueryInformationProcess=function(
Handle : THandle;
infoClass : TProcessInfoClass;
processInformation : Pointer;
processInformationLength : ULONG;
returnLength : PULONG
) : DWORD; stdcall;

var DebuggerThread: TDebugger;
    Semaphore: Thandle;

    DbgUIDebugActiveProcess:TDbgUIDebugActiveProcess;
    DebugBreakProcess:TDebugBreakProcess;
    DebugActiveProcessStop:TDebugActiveProcessStop;
    DebugSetProcessKillOnExit:TDebugSetProcessKillOnExit;
    IsDebuggerPresent:TIsDebuggerPresent;
    ntSuspendProcess: TntSuspendProcess;
    ntResumeProcess: tntResumeProcess;

    NtQueryInformationProcess: TNtQueryInformationProcess;
    IsDebuggerPresentLocation:dword;
    DbgBreakPointLocation:dword;


    krn: thandle;
    ntdlllib: thandle;

    CRDebugging: TCriticalSection;


  function startdebuggerifneeded: boolean; overload;
  function startdebuggerifneeded(ask:boolean): boolean; overload;
  function breakthread(threadhandle: thandle):boolean;
  function DebugActiveProcessStopProstitute(x: dword): boolean;
  function ToggleBreakpoint(address:dword):boolean;

implementation

uses {$ifndef net}Mainunit,Memorybrowserformunit,{$endif}disassembler{$ifndef net},frmTracerUnit,foundcodeunit,debugger2,advancedoptionsunit,formChangedAddresses,frmstacktraceunit,frmThreadlistunit,formdebugstringsunit,formsettingsunit,processwindowunit,plugin,frmCreatedProcessListUnit{$endif};

function ToggleBreakpoint(address:dword):boolean;
{$ifndef net}
procedure setbreakpoints;
var i: integer;
begin
  with debuggerthread do
  begin
    //set the debug breakpoint
    suspend;
    DRRegs.ContextFlags:=CONTEXT_DEBUG_REGISTERS;
    DRRegs.Dr7:=reg0set or reg1set or reg2set or reg3set;

    DRRegs.Dr0:=0;
    drregs.dr1:=0;
    drregs.dr2:=0;

    for i:=0 to length(userbreakpoints)-1 do
    begin
      if i=0 then DRRegs.Dr0:=userbreakpoints[0] else
      if i=1 then DRRegs.Dr1:=userbreakpoints[1] else
      if i=2 then DRRegs.Dr2:=userbreakpoints[2];
    end;

    for i:=0 to length(threadlist)-1 do
    begin
      suspendthread(debuggerthread.threadlist[i][1]);
      setthreadcontext(debuggerthread.threadlist[i][1],debuggerthread.DRRegs);
      resumethread(debuggerthread.threadlist[i][1]);
    end;

    Resume;
  end;

end;

var i,j,k: integer;
    a,original,written: dword;

    int3: byte;
{$endif}

begin
{$ifndef net}
  result:=false;

  if foundcodedialog<>nil then
    raise exception.Create('I can''t do that! You are currently using one of the code finder options, please, stop it first');  

  if debuggerthread2<>nil then
  begin
    for i:=0 to 3 do
    begin
      if debuggerthread2.breakpoints[i]=address then
      begin
        outputdebugstring('Going to disable this changereg breakpoint');
        if debuggerthread2.breakpointchanges[i].address<>0 then
        begin
          StopRegisterChange(i);
          debuggerthread2.breakpointchanges[i].address:=0;
        end;

        debuggerthread2.breakpoints[i]:=0;
        debuggerthread2.setbreakpoints;
        memorybrowser.updatebplist;

        result:=false;
        for j:=0 to 3 do
          if debuggerthread2.breakpoints[j]<>0 then
          begin
            result:=true;
            break;
          end;

        if not result then freeandnil(debuggerthread2);

        exit;
      end;
    end;
  end;


  if not startdebuggerifneeded then exit;
  int3:=$cc;


  //still here so the debugger has been attached to the process or i've fucked up again

  with debuggerthread do
  begin

    try
      WaitForSingleObject(semaphore,infinite);
      userisdebugging:=true;

      if formsettings.rbDebugAsBreakpoint.checked then
      begin
        //try to see if it already is in the list
        for i:=0 to length(userbreakpoints)-1 do
          if userbreakpoints[i]=address then
          begin
            //if it is then remove the breakpoint
            for j:=i to length(userbreakpoints)-2 do
              userbreakpoints[j]:=userbreakpoints[j+1];
            setlength(userbreakpoints,length(userbreakpoints)-1);

            //also remove the registermodificationBP
            for j:=0 to length(debuggerthread.registermodificationBPs)-1 do
              if registermodificationBPs[j].address=address then
              begin

⌨️ 快捷键说明

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