Пример #1
0
 public void Int3Check() {
     var addresses = new ulong[] { 0x7FF9C61653E0 };
     foreach (var address in addresses) {
         var b = DebugProcessUtils.ReadByte(CurrentProcess, address);
         var overwritten = false;
         if (b == AssemblyUtil.Int3) {
             DebugProcessUtils.WriteByte(CurrentProcess, address, AssemblyUtil.Nop);
             overwritten = true;
         }
         LoggerInstance.WriteLine($"checking int3 at: 0x{address:X}, overwritten: {overwritten}");
     }
 }
Пример #2
0
        public bool ResumeBreak(bool trace = true) {
            //Console.WriteLine("ResumeBreak");
            //for (var i = 0; i < 10000; i++) {
            var done = false;
            var goNextBreakPoint = false;
            var continueCode = Win32Imports.DbgContinue;
            while (!done)
            {
                Win32Imports.DebugEvent evt;
                if (!Win32Imports.WaitForDebugEvent(out evt, 0)) {
                //if (!handleDebugEvent(out evt, out continueCode)) {
                        //Console.WriteLine("WaitForDebugEvent failed");
                        //throw new Win32Exception();
                        done = true;
                }
                else {
                    CurrentInfo.EventCount++;

                    // Multiple if's for easier debugging at this moment
                    switch (evt.dwDebugEventCode) {
                        case Win32Imports.DebugEventType.LoadDllDebugEvent:
                            //Console.WriteLine($"resumed load dll event: {evt.dwThreadId}");
                            break;
                        case Win32Imports.DebugEventType.UnloadDllDebugEvent:
                            //Console.WriteLine($"resumed unload dll event: {evt.dwThreadId}");
                            break;
                        case Win32Imports.DebugEventType.ExceptionDebugEvent:
                            var exceptionAddress = (ulong) evt.Exception.ExceptionRecord.ExceptionAddress.ToInt64(); 

                            //Console.WriteLine($"first addr: {breakAddress:X} vs {address:X}");
                            var context = new Win32Imports.ContextX64();
                            var breakAddress = getRip((uint) evt.dwThreadId, ref context, GetRipAction.ActionGetContext);
                            var code = evt.Exception.ExceptionRecord.ExceptionCode;
                            //Console.WriteLine($"code: {code}, events: {eventCount}, thread: {evt.dwThreadId}, addr: {breakAddress2:X} vs {address:X}");

                            if (BreakPoints.ContainsKey(breakAddress) && BreakPoints[breakAddress].IsActive) {
                                LoggerInstance.WriteLine($"match at {breakAddress:X}, trace: {trace}");

                                setTrace((uint)evt.dwThreadId);
                                UninstallBreakPoint(breakAddress);
                                _lastBreakAddress = breakAddress;

                                CurrentInfo.LastContext = context;
                                CurrentInfo.LastContextReady = true;
                                // trace
                                //setTrace((uint) evt.dwThreadId, false);
                                if (BreakPoints[breakAddress].Description.Equals(CloseHandleDescription)) {
                                    LoggerInstance.WriteLine("CloseHandle hit");
                                    LoggerInstance.WriteLine("Registers:" + AssemblyUtil.FormatContext(context));
                                } else {
                                }
                                done = BreakPointCallBack(this, evt.dwThreadId, context, trace).StepOver;
                                goNextBreakPoint = done;
                                //} else if (!CheckBreakPointActive()) {
                            }
                            else {
                                // if we have seen it before
                                var shouldTrace = !BreakPoints.ContainsKey(breakAddress) ||
                                    !(BreakPoints.ContainsKey(breakAddress) && !BreakPoints[breakAddress].ShouldEnable) ||
                                    !(BreakPoints.ContainsKey(breakAddress) && !BreakPoints[breakAddress].IsActive);
                                // no breakpoint active, so we are tracing
                                if (trace && shouldTrace) {
                                    LoggerInstance.WriteLine($"tracing thread {evt.dwThreadId} at 0x{breakAddress:X}");
                                    var ret = BreakPointCallBack(this, evt.dwThreadId, context, true);
                                    done = ret.StepOver;
                                    goNextBreakPoint = done;
                                    if (ret.Ignore) {
                                        LoggerInstance.WriteLine("continuing with exception handlers");
                                        continueCode = Win32Imports.DbgExceptionNotHandled;
                                    }
                                }
                                else {
                                    LoggerInstance.WriteLine("continuing with exception handlers");
                                    continueCode = Win32Imports.DbgExceptionNotHandled;
                                }
                            }

                            Instruction instr = null;
                            string asm = "N/A";
                            string asm2 = "N/A";
                            try {
                                instr = AssemblyUtil.Disassemble(CurrentProcess, exceptionAddress);
                                asm = AssemblyUtil.FormatInstruction(AssemblyUtil.Disassemble(CurrentProcess, breakAddress));
                                asm2 = AssemblyUtil.FormatInstruction(AssemblyUtil.Disassemble(CurrentProcess, exceptionAddress));
                            }
                            catch (Exception)
                            {
                                // ignored
                            }

                            string msg;

                            switch (code) {
                                case Win32Imports.ExceptionCodeStatus.ExceptionSingleStep:
                                    asm = AssemblyUtil.FormatInstruction(AssemblyUtil.Disassemble(CurrentProcess, breakAddress));
                                    LoggerInstance.WriteLine($"single step at {breakAddress:X}, evtCount: {CurrentInfo.EventCount}, asm: {asm}");
                                    continueCode = HasBreakPoint(breakAddress) ? Win32Imports.DbgContinue : Win32Imports.DbgExceptionNotHandled;
                                    break;
                                case Win32Imports.ExceptionCodeStatus.ExceptionBreakpoint:        
                                    asm = AssemblyUtil.FormatInstruction(instr);
                                    //if (instr.Mnemonic.Equals("INT") && instr.Operands.Equals("3")) {
                                    if (instr != null && instr.Mnemonic == ud_mnemonic_code.UD_Iint3) {
                                        LoggerInstance.WriteLine($"int3 breakpoint at: {exceptionAddress:X}, evtCount: {CurrentInfo.EventCount}, asm: {asm}");
                                        LoggerInstance.WriteLine("overwriting with NOP");
                                        DebugProcessUtils.WriteByte(CurrentProcess, exceptionAddress, AssemblyUtil.Nop);
                                        continueCode = Win32Imports.DbgContinue;
                                    } else {
                                        msg = $"breakpoint, chance: { evt.Exception.dwFirstChance}";
                                        msg += $", at: 0x{breakAddress:X}, exc at: 0x{exceptionAddress:X}, asm: {asm}, exc asm: {asm2}";
                                        LoggerInstance.WriteLine(msg);
                                    }
                                    break;
                                case Win32Imports.ExceptionCodeStatus.ExceptionInvalidHandle:
                                    msg = $"invalid handle, chance: { evt.Exception.dwFirstChance}";
                                    msg += $", at: 0x{breakAddress:X}, exc at: 0x{exceptionAddress:X}, asm: {asm}, exc asm: {asm2}";
                                    LoggerInstance.WriteLine(msg);
                                    LoggerInstance.WriteLine(msg);
                                    AssemblyUtil.LogStackTrace(_importResolver, LoggerInstance, CurrentProcess, context.Rsp);
                                    continueCode = Win32Imports.DbgExceptionNotHandled;
                                    break;
                                case Win32Imports.ExceptionCodeStatus.ExceptionInvalidOperation:
                                    msg = $"invalid operation, chance: { evt.Exception.dwFirstChance}";
                                    msg += $", at: 0x{breakAddress:X}, exc at: 0x{exceptionAddress:X}, asm: {asm}, exc asm: {asm2}";
                                    // anti-anti-debug measure
                                    if (instr != null && instr.Mnemonic == ud_mnemonic_code.UD_Iud2) {
                                        LoggerInstance.WriteLine("overwriting UD2 with NOP");
                                        DebugProcessUtils.WriteBytes(CurrentProcess, exceptionAddress, new[] { AssemblyUtil.Nop, AssemblyUtil.Nop });
                                    }
                                    // anti-anti-debug measure
                                    var instr2 = AssemblyUtil.Disassemble(CurrentProcess, exceptionAddress - 1);
                                    if (instr2.Mnemonic == ud_mnemonic_code.UD_Iint && instr2.Operands[0].Value == 0x2D) {
                                        ulong rip = context.Rip - 1;
                                        setRip((uint) evt.dwThreadId, false, rip);
                                        LoggerInstance.WriteLine("INT2D encountered, subtracting 1 from Rip");
                                        continueCode = Win32Imports.DbgContinue;
                                    } else {
                                        continueCode = Win32Imports.DbgExceptionNotHandled;
                                    }
                                    LoggerInstance.WriteLine(msg);                                    
                                    break;
                                case Win32Imports.ExceptionCodeStatus.ExceptionAccessViolation:
                                    msg = $"access violation: {code:X}, chance: { evt.Exception.dwFirstChance}";
                                    msg += $", at: 0x{breakAddress:X}, exc at: 0x{exceptionAddress:X}, asm: {asm}, exc asm: {asm2}";
                                    LoggerInstance.WriteLine(msg);
                                    break;
                                case 0:
                                    LoggerInstance.WriteLine($"event 0 at: {breakAddress:X}");
                                    break;
                                default:
                                    msg = $"unknown code: {code:X}, chance: { evt.Exception.dwFirstChance}";
                                    msg += $", at: 0x{breakAddress:X}, exc at: 0x{exceptionAddress:X}, asm: {asm}, exc asm: {asm2}";
                                    LoggerInstance.WriteLine(msg);
                                    break;
                            }
                            break;
                        case Win32Imports.DebugEventType.CreateProcessDebugEvent:
                            //Console.WriteLine($"resumed create process event for thread {evt.dwThreadId}");
                            break;
                        case Win32Imports.DebugEventType.CreateThreadDebugEvent:
                            //Console.WriteLine($"resumed create thread event for thread {evt.dwThreadId}");
                            break;
                        case Win32Imports.DebugEventType.ExitThreadDebugEvent:
                            //Console.WriteLine($"resumed exit thread event for thread {evt.dwThreadId}");
                            break;
                        case Win32Imports.DebugEventType.ExitProcessDebugEvent:
                            Console.WriteLine($"resumed exit process event for thread {evt.dwThreadId}");
                            break;
                        default:
                            Console.WriteLine($"resumed debug event for thread: {evt.dwThreadId} {evt.dwDebugEventCode}");
                            break;
                    }

                    
                    //LoggerInstance.WriteLine($"debug event of type {evt.dwDebugEventCode}");

                    if (!Win32Imports.ContinueDebugEvent(evt.dwProcessId, evt.dwThreadId, continueCode)) {
                        throw new Win32Exception();
                    }
                    //ContinueDebugEvent(evt.dwProcessId, evt.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
                    //setBreakPoint((uint) evt.dwThreadId, address, false);
                }
            }

            //Console.WriteLine("End ResumeBreak");
            //return events;
            return goNextBreakPoint;
        }