/// <summary>
        /// Starts the characterbuilder and modifies the in-memory representation of LOADED_FILE to
        /// support unencrypted data.
        /// </summary>
        /// <param name="patchFile"></param>
        public static void StartProcessAndPatchMemory()
        {
            Log.Debug("About to start loading character builder.");
            //// start character builder
            NativePipeline np = new NativePipeline();

            Log.Debug("Creating process and attaching debugger");
            NativeDbgProcess proc = np.CreateProcessDebug(EXECUTABLE, EXECUTABLE_ARGS);

            while (true)
            {
                Log.Debug("Waiting for next event");
                NativeEvent ne = np.WaitForDebugEventInfinite();
                Log.Debug(ne.ToString());
                ne.Process.HandleIfLoaderBreakpoint(ne);
                if (ne.EventCode == NativeDebugEventCode.LOAD_DLL_DEBUG_EVENT)
                {
                    DllBaseNativeEvent ev = (DllBaseNativeEvent)ne;
                    if (ev.Module.Name.Contains(LOADED_FILE))
                    {
                        patchMemory(ev, (uint)proc.Id);
                        np.ContinueEvent(ne);
                        np.Detach(proc);
                        break;
                    }
                }
                np.ContinueEvent(ne);
            }
        }
Esempio n. 2
0
        NativeDbgProcess CreateNew(int processId)
        {
            NativeDbgProcess process = new NativeDbgProcess(processId);

            m_processes[processId] = process;
            return(process);
        }
Esempio n. 3
0
        /// <summary>
        /// Stop debugging the specified process (detach)
        /// </summary>
        /// <param name="process">process to detach from</param>
        /// <remarks>After detaching, the process is removed from the caches and can not be accessed. If detaching at a debug
        /// event, do not call Continue on the event. </remarks>
        public void Detach(NativeDbgProcess process)
        {
            if (process == null)
            {
                throw new ArgumentNullException("process");
            }
            EnsureIsOnWin32EventThread();

            int  pid       = process.Id;
            bool fDetachOk = NativeMethods.DebugActiveProcessStop((uint)pid);

            if (!fDetachOk)
            {
                int err = Marshal.GetLastWin32Error();
                throw new InvalidOperationException("Failed to detach to process " + pid + "error=" + err);
            }
            RemoveProcess(pid);
        }
Esempio n. 4
0
        /// <summary>
        /// Continue a debug event previously gotten by WaitForDebugEvent
        /// </summary>
        /// <param name="nativeEvent"></param>
        /// <remarks>Can't continue a debug event if we just detached from the process</remarks>
        public void ContinueEvent(NativeEvent nativeEvent)
        {
            if (nativeEvent == null)
            {
                throw new ArgumentNullException("nativeEvent");
            }
            if (nativeEvent.ContinueStatus == NativeMethods.ContinueStatus.CONTINUED)
            {
                throw new ArgumentException("event was already continued", "nativeEvent");
            }
            if (nativeEvent.Pipeline != this)
            {
                throw new ArgumentException("event does not belong to this pipeline");
            }
            EnsureIsOnWin32EventThread();

            // Verify that the process for this event is still connected to our pipeline.
            // The lookup will throw if the process detached or was terminated.
            NativeDbgProcess proc = nativeEvent.Process;

            Debug.Assert(proc.Id == nativeEvent.ProcessId);


            nativeEvent.DoCleanupForContinue();

            bool fContinueOk = NativeMethods.ContinueDebugEvent((uint)nativeEvent.ProcessId, (uint)nativeEvent.ThreadId, nativeEvent.ContinueStatus);

            if (!fContinueOk)
            {
                int err = Marshal.GetLastWin32Error();
                throw new InvalidOperationException("Continue failed on process " + nativeEvent.ProcessId + " error=" + err);
            }

            // Mark as continued so that we don't accidentally continue again.
            nativeEvent.ContinueStatus = NativeMethods.ContinueStatus.CONTINUED;
        }
Esempio n. 5
0
        public void DebugEventHandler()
        {
            NativePipeline   dbg     = new NativePipeline();
            NativeDbgProcess process = dbg.Attach(_pid);

            _attached = true;

            // Tell the process it is ready to resume
            try
            {
                _process.PyProcess.on_handle_first_bp();
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("ERROR: Python class 'Process' {0} failed when executing 'on_handle_first_bp()':", _process.GetName()));
                Console.WriteLine(ex.ToString());
                // attempt to continue anyways
            }


            // Initialize the printing variables
            DateTime  numEvents_lastPrintTime = DateTime.Now;
            Hashtable numEventsByTarget       = new Hashtable(0x1000);

            _breakpointInfo = new Hashtable(10);
            bool printReport              = false;
            bool processReady             = false;
            bool loaderBreakpointReceived = false;
            bool wx86BreakpointReceived   = false;

            while (_processingEvents)
            {
                if (DateTime.Now.Subtract(numEvents_lastPrintTime).TotalSeconds >= 1)
                {
                    // Print the number of events in the last second
                    if (printReport && numEventsByTarget.Count > 0)
                    {
                        PrintReport(numEventsByTarget);
                    }

                    numEvents_lastPrintTime = DateTime.Now;
                    numEventsByTarget.Clear();
                }

                // Check to see if the process has loaded
                if (!processReady)
                {
                    processReady = HandleProcessReady(wx86BreakpointReceived);
                }

                NativeEvent e = dbg.WaitForDebugEvent(100);

                // Check to see if the process has loaded
                if (!processReady)
                {
                    processReady = HandleProcessReady(wx86BreakpointReceived);
                }

                if (_keepOnExit && dbg.KillOnExit)
                {
                    dbg.KillOnExit = false;
                }

                if (e != null)
                {
                    //Console.WriteLine(e.ToString());
                    e.Process.HandleIfLoaderBreakpoint(e, ref loaderBreakpointReceived);

                    switch (e.EventCode)
                    {
                    case NativeDebugEventCode.EXCEPTION_DEBUG_EVENT:
                        HandleNativeDebugEvent((ExceptionNativeEvent)e, ref numEventsByTarget, ref wx86BreakpointReceived);
                        break;

                    case NativeDebugEventCode.LOAD_DLL_DEBUG_EVENT:
                        // Start of the process, ntdll.dll and kernel32.dll should now be loaded. Trigger a Process.HandleProcessLoaded() event.
                        if (_process.PyProcess.print_debugger_messages)
                        {
                            Console.WriteLine(e.ToString());
                        }

                        //Console.WriteLine(((LoadDllNativeEvent)e).Module.Name );
                        _process.HandleModuleLoaded((LoadDllNativeEvent)e);

                        break;

                    case NativeDebugEventCode.EXIT_PROCESS_DEBUG_EVENT:
                        // Process crashed, send Process.ProcessTerminated() event and finish.
                        if (printReport && numEventsByTarget.Count > 0)
                        {
                            PrintReport(numEventsByTarget);
                        }
                        _process.HandleProcessTerminated();
                        dbg.Dispose();
                        _attached = false;
                        return;

                    default:
                        break;
                    }

                    // Resume event
                    dbg.ContinueEvent(e);
                }
            }

            // Detach
            dbg.KillOnExit = false;
            _attached      = false;
        }