private IDebugBreakpoint2 SetBreakpoint(UInt64 address, DEBUG_BREAKPOINT_TYPE breakpointType, DEBUG_BREAKPOINT_ACCESS_TYPE access, UInt32 size) { const UInt32 AnyId = UInt32.MaxValue; IDebugBreakpoint2 breakpoint = null; this.BeginInterrupt(); Task.Factory.StartNew(() => { try { this.CheckHandleResult(this.Control.AddBreakpoint2(breakpointType, AnyId, out breakpoint)); breakpoint.SetOffset(address); breakpoint.SetFlags(DEBUG_BREAKPOINT_FLAG.ENABLED); breakpoint.SetDataParameters(size, access); this.Control.SetExecutionStatus(DEBUG_STATUS.GO); } catch (Exception ex) { Logger.Log(LogLevel.Error, "Error setting breakpoint", ex); } }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, this.Scheduler.ExclusiveScheduler).Wait(); this.EndInterrupt(); return(breakpoint); }
/// <summary> /// Constructor for creating new breakpoints. /// </summary> /// <param name="breakpointSpec">Spec describing this breakpoint.</param> /// <param name="invalidateCache">Invalidate cache action.</param> /// <param name="dbgEngDll">DbgEngDll interface.</param> /// <remarks> /// This about adding some sort of factory pattern here. /// </remarks> public DbgEngBreakpoint(BreakpointSpec breakpointSpec, Action invalidateCache, DbgEngDll dbgEngDll) { this.breakpointAction = breakpointSpec.BreakpointAction; this.invalidateCache = invalidateCache; unchecked { if (breakpointSpec.BreakpointType == BreakpointType.Code) { breakpoint = dbgEngDll.Control.AddBreakpoint2((uint)Defines.DebugBreakpointCode, (uint)Defines.DebugAnyId); } else { throw new NotImplementedException("Only supports Code breakpoints"); } } breakpoint.SetOffset(breakpointSpec.BreakpointAddress); breakpoint.SetFlags((uint)Defines.DebugBreakpointEnabled); breakpointStatusEnabled = true; }
public static void Run(Process clProcess) { ProcessModuleCollection clProcessModules = clProcess.Modules; ///////////////////////////////// Guid guid = typeof(IDebugClient).GUID; // create debug client object //object obj; //CheckHr(Native.NativeMethods.DbgEng.DebugCreate(ref guid, out obj)); IntPtr pObj = IntPtr.Zero; CheckHr(Native.NativeMethods.DbgEng.DebugCreate(ref guid, ref pObj)); IDebugClient5Fixed client = (IDebugClient5Fixed)Marshal.GetTypedObjectForIUnknown(pObj, typeof(IDebugClient5Fixed)); IDebugDataSpaces4 dataSpaces = client as IDebugDataSpaces4; IDebugRegisters2Fixed registers = client as IDebugRegisters2Fixed; //IDebugClient5Fixed client = obj as IDebugClient5Fixed; IDebugControl6 control = client as IDebugControl6; var events = new EventCallbacks(control); client.SetEventCallbacksWide(events); client.SetOutputCallbacksWide(new OutputCallbacks()); Console.CancelKeyPress += (s, e) => { e.Cancel = true; //control.SetInterrupt(DEBUG_INTERRUPT.ACTIVE); }; CheckHr(client.AttachProcess(0, (uint)clProcess.Id, DEBUG_ATTACH.DEFAULT)); /////////// ProcessModule progModule = null; foreach (ProcessModule module in clProcessModules) { if (module.ModuleName == "prog.dll") { progModule = module; break; } } Console.WriteLine( $"Module: {progModule.ModuleName}\r\n" + $" BaseAddress: {progModule.BaseAddress.FormatAsHex()}\r\n" + $" EntryPointAddress: {progModule.EntryPointAddress.FormatAsHex()}\r\n" + $" ModuleMemorySize: 0x{progModule.ModuleMemorySize:X8}\r\n" + $""); //callbackProvider = new UnmanagedCodeSupplier((PickUpWeaponDelegate)ttExecutionCallback, IntPtr.Size == sizeof(int) ? x86CodeForFastcallWrapperForExecutionDelegate : x64CodeForFastcallWrapperForExecutionDelegate, IntPtr.Size == sizeof(int) ? new UIntPtr(0xF0F0F0F0) : new UIntPtr(0xF0F0F0F0F0F0F0F0)); //byte[] progMemory = new byte[progModule.ModuleMemorySize]; //return; //////// CheckHr(control.WaitForEvent(DEBUG_WAIT.DEFAULT, 5000)); byte[] progMemory = new byte[progModule.ModuleMemorySize]; uint readMemoryBytes; ulong validbase; uint validsize; CheckHr(dataSpaces.GetValidRegionVirtual((ulong)progModule.BaseAddress, (uint)progMemory.Length, out validbase, out validsize)); //Console.WriteLine($"Read {readMemoryBytes} bytes"); byte[] pickUpWeaponSignature; byte[] wildcard; ParseSearchPattern( "55 8B EC 83 E4 F8 80 3D A9 0F ?? 0F 00 56 57 8B F2 8B F9 75 23 80 3D 9A 0E ?? 0F 00 75 1A 56 E8 9C 94 F9 FF 83 FE 0F 75 0F 83 F8 32 7C 0A B9 D4", out pickUpWeaponSignature, out wildcard ); //wildcard[3] = 1; ulong matchOffset; CheckHr(dataSpaces.ReadVirtualUncached((ulong)progModule.BaseAddress, progMemory, (uint)progMemory.Length, out readMemoryBytes)); fixed(void *progMemoryPtr = progMemory, pickUpWeaponSignaturePtr = pickUpWeaponSignature, wildcardPtr = wildcard) { //pickUpWeaponAddress = (IntPtr) IndexOfUnchecked(progMemoryPtr, progMemory.Length, pickUpWeaponSignaturePtr, pickUpWeaponSignature.Length, wildcardPtr); int pickUpWeaponAddressOffset = IndexOfUnchecked(progMemoryPtr, progMemory.Length, pickUpWeaponSignaturePtr, pickUpWeaponSignature.Length, wildcardPtr); Console.WriteLine($"PickUpWeapon offset: 0x{pickUpWeaponAddressOffset:X8}"); if (pickUpWeaponAddressOffset == -1) { throw new Exception("Pattern not found!"); } pickUpWeaponAddress = new IntPtr(pickUpWeaponAddressOffset + (int)progModule.BaseAddress); } //dataSpaces.SearchVirtual((ulong) progModule.BaseAddress, (ulong) progModule.ModuleMemorySize, pickUpWeaponSignature, (uint) pickUpWeaponSignature.Length, 1, out matchOffset); //pickUpWeaponAddress = (IntPtr) matchOffset; Console.WriteLine($"PickUpWeapon address: {pickUpWeaponAddress.FormatAsHex()}"); control.AddBreakpoint2(DEBUG_BREAKPOINT_TYPE.CODE, uint.MaxValue, out pickUpWeaponBreakpoint); pickUpWeaponBreakpoint.SetOffset((ulong)pickUpWeaponAddress); pickUpWeaponBreakpoint.SetFlags(DEBUG_BREAKPOINT_FLAG.ENABLED); pickUpWeaponBreakpoint.SetCommandWide(".echo WEAPON PICKUP!"); // fixed (void* progMemoryPtr = progMemory, pickUpWeaponSignaturePtr = pickUpWeaponSignature) { // int pickUpWeaponAddressOffset = // IndexOfUnchecked(progMemoryPtr, progMemory.Length, pickUpWeaponSignaturePtr, pickUpWeaponSignature.Length); // Console.WriteLine($"PickUpWeapon offset: 0x{pickUpWeaponAddressOffset:X8}"); // if (pickUpWeaponAddressOffset == -1) // throw new Exception("Pattern not found!"); // // pickUpWeaponAddress = new IntPtr(pickUpWeaponAddressOffset + (int) progModule.BaseAddress); // Console.WriteLine($"PickUpWeapon address: {pickUpWeaponAddress.FormatAsHex()}"); // } control.SetExecutionStatus(DEBUG_STATUS.GO); File.WriteAllBytes("dump.bin", progMemory); DEBUG_STATUS status; int hr; while (true) { CheckHr(control.GetExecutionStatus(out status)); if (status == DEBUG_STATUS.NO_DEBUGGEE) { Console.WriteLine("No Target"); break; } if (status == DEBUG_STATUS.GO || status == DEBUG_STATUS.STEP_BRANCH || status == DEBUG_STATUS.STEP_INTO || status == DEBUG_STATUS.STEP_OVER) { hr = control.WaitForEvent(DEBUG_WAIT.DEFAULT, uint.MaxValue); continue; } if (events.StateChanged) { Console.WriteLine(); events.StateChanged = false; if (events.BreakpointHit) { control.OutputCurrentState(DEBUG_OUTCTL.THIS_CLIENT, DEBUG_CURRENT.DEFAULT); events.BreakpointHit = false; } } control.OutputPromptWide(DEBUG_OUTCTL.THIS_CLIENT, null); Console.Write(" "); Console.ForegroundColor = ConsoleColor.Gray; string command = Console.ReadLine(); if (command == ".detach") { client.DetachCurrentProcess(); } else { control.ExecuteWide(DEBUG_OUTCTL.THIS_CLIENT, command, DEBUG_EXECUTE.DEFAULT); } } }