微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从C#代码自动debugging进程并读取寄存器值

我正在寻找一种方法来阅读edxregistry在某个地址,如问题在这个问题: 阅读eax寄存器

尽pipe我的解决scheme需要使用C#,而我试图做到这一点,但我现在得到的是:

public static IntPtr GetEdx(IntPtr address,Process process) { const uint DBG_EXCEPTION_NOT_HANDLED = 0x80010001; const uint EXCEPTION_SINGLE_STEP = 0x80000004; const int DBG_CONTINUE = 0x00010002; // Seems to work better than DBG_EXCEPTION_NOT_HANDLED //DebugSetProcessKillOnExit(0); DEBUG_EVENT evt = new DEBUG_EVENT(); // Attach to the process we provided the thread as an argument if (!DebugActiveProcess(process.Id)) throw new Win32Exception(); CONTEXT context = new CONTEXT(); foreach (Processthread thread in process.Threads) { uint iThreadId = (uint)thread.Id; IntPtr hThread = OpenThread( ThreadAccessFlags.SUSPEND_RESUME | ThreadAccessFlags.SET_CONTEXT | ThreadAccessFlags.GET_CONTEXT,false,iThreadId); // Suspent the thread if (SuspendThread(hThread) == -1) throw new ApplicationException("Cannot suspend thread."); context = new CONTEXT { ContextFlags = (uint)CONTEXT_FLAGS.CONTEXT_DEBUG_REGISTERS | (uint)CONTEXT_FLAGS.CONTEXT_INTEGER }; // Get the context if (!Getthreadcontext(hThread,ref context)) throw new Win32Exception(); // Change the context context.Dr0 = (uint)address; context.Dr7 = 0x00000001; // Set the changed context back if (!Setthreadcontext(hThread,ref context)) throw new Win32Exception(); // Check if setting the context give any errors var error = Marshal.GetLastWin32Error(); if (error != 0) { throw new ApplicationException("Error is setting context."); } // Resume the thread if (ResumeThread(hThread) == -1) throw new ApplicationException("Cannot resume thread."); } while (true) { if (!WaitForDebugEvent(out evt,-1)) throw new Win32Exception(); // Multiple if's for easier debugging at this moment if (evt.dwDebugEventCode == (uint)DebugEventType.EXCEPTION_DEBUG_EVENT) { if (evt.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_SINGLE_STEP) { if (evt.Exception.ExceptionRecord.ExceptionAddress == address) { context = new CONTEXT { ContextFlags = (uint)CONTEXT_FLAGS.CONTEXT_DEBUG_REGISTERS | (uint)CONTEXT_FLAGS.CONTEXT_INTEGER }; Getthreadcontext((IntPtr)evt.dwThreadId,ref context); return (IntPtr)context.Ebx; // ebx get } } } ContinueDebugEvent(evt.dwProcessId,evt.dwThreadId,DBG_CONTINUE);//DBG_EXCEPTION_NOT_HANDLED); } }

有了很多的Kernel32方法

[DllImport("kernel32.dll")] static extern int ResumeThread(IntPtr hThread); [DllImport("kernel32.dll")] static extern uint SuspendThread(IntPtr hThread); [DllImport("kernel32.dll")] public static extern IntPtr OpenThread(ThreadAccessFlags dwDesiredAccess,bool bInheritHandle,uint dwThreadId); [DllImport("Kernel32.dll",SetLastError = true)] static extern bool DebugActiveProcess(int dwProcessId); [DllImport("Kernel32.dll",SetLastError = true)] static extern bool WaitForDebugEvent([Out] out DEBUG_EVENT lpDebugEvent,int dwMilliseconds); [DllImport("Kernel32.dll",SetLastError = true)] static extern bool ContinueDebugEvent(int dwProcessId,int dwThreadId,uint dwContinueStatus); [DllImport("Kernel32.dll",SetLastError = true)] public static extern bool IsDebuggerPresent(); [DllImport("kernel32.dll")] private static extern bool Getthreadcontext(IntPtr hThread,ref CONTEXT lpContext); [DllImport("kernel32.dll")] public static extern bool Setthreadcontext(IntPtr hThread,ref CONTEXT lpContext); [StructLayout(LayoutKind.Sequential)] public unsafe struct DEBUG_EVENT { public readonly uint dwDebugEventCode; public readonly int dwProcessId; public readonly int dwThreadId; [MarshalAs(UnmanagedType.ByValArray,SizeConst = 86,ArraySubType = UnmanagedType.U1)] private readonly byte[] debugInfo; public EXCEPTION_DEBUG_INFO Exception { get { if (debugInfo == null) return new EXCEPTION_DEBUG_INFO(); fixed (byte* ptr = debugInfo) { return *(EXCEPTION_DEBUG_INFO*)ptr; } } } public LOAD_DLL_DEBUG_INFO LoadDll { get { if (debugInfo == null) return new LOAD_DLL_DEBUG_INFO(); fixed (byte* ptr = debugInfo) { return *(LOAD_DLL_DEBUG_INFO*)ptr; } } } } [StructLayout(LayoutKind.Sequential)] public struct LOAD_DLL_DEBUG_INFO { public readonly IntPtr hFile; public readonly IntPtr lpBaSEOfDll; public readonly uint dwDebugInfoFileOffset; public readonly uint nDebugInfoSize; public readonly IntPtr lpImageName; public readonly ushort fUnicode; } [StructLayout(LayoutKind.Sequential)] public struct EXCEPTION_DEBUG_INFO { public EXCEPTION_RECORD ExceptionRecord; public readonly uint dwFirstChance; } [StructLayout(LayoutKind.Sequential)] public struct EXCEPTION_RECORD { public readonly uint ExceptionCode; public readonly uint ExceptionFlags; public readonly IntPtr ExceptionRecord; public readonly IntPtr ExceptionAddress; public readonly uint NumberParameters; //[MarshalAs(UnmanagedType.ByValArray,SizeConst = 15,ArraySubType = UnmanagedType.U4)] //public readonly uint[] Exception@R_785_4045@ion; public unsafe fixed uint Exception@R_785_4045@ion[15]; } public enum DebugEventType : int { CREATE_PROCESS_DEBUG_EVENT = 3,//Reports a create-process debugging event. The value of u.CreateProcessInfo specifies a CREATE_PROCESS_DEBUG_INFO structure. CREATE_THREAD_DEBUG_EVENT = 2,//Reports a create-thread debugging event. The value of u.CreateThread specifies a CREATE_THREAD_DEBUG_INFO structure. EXCEPTION_DEBUG_EVENT = 1,//Reports an exception debugging event. The value of u.Exception specifies an EXCEPTION_DEBUG_INFO structure. EXIT_PROCESS_DEBUG_EVENT = 5,//Reports an exit-process debugging event. The value of u.ExitProcess specifies an EXIT_PROCESS_DEBUG_INFO structure. EXIT_THREAD_DEBUG_EVENT = 4,//Reports an exit-thread debugging event. The value of u.ExitThread specifies an EXIT_THREAD_DEBUG_INFO structure. LOAD_DLL_DEBUG_EVENT = 6,//Reports a load-dynamic-link-library (DLL) debugging event. The value of u.LoadDll specifies a LOAD_DLL_DEBUG_INFO structure. OUTPUT_DEBUG_STRING_EVENT = 8,//Reports an output-debugging-string debugging event. The value of u.DebugString specifies an OUTPUT_DEBUG_STRING_INFO structure. RIP_EVENT = 9,//Reports a RIP-debugging event (system debugging error). The value of u.RipInfo specifies a RIP_INFO structure. UNLOAD_DLL_DEBUG_EVENT = 7,//Reports an unload-DLL debugging event. The value of u.UnloadDll specifies an UNLOAD_DLL_DEBUG_INFO structure. } [StructLayout(LayoutKind.Sequential)] public struct CONTEXT { public uint ContextFlags; public uint Dr0; public uint Dr1; public uint Dr2; public uint Dr3; public uint Dr6; public uint Dr7; public FLOATING_SAVE_AREA FloatSave; public uint SegGs; public uint SegFs; public uint SegEs; public uint SegDs; public uint Edi; public uint Esi; public uint Ebx; public uint Edx; public uint Ecx; public uint Eax; public uint Ebp; public uint Eip; public uint SegCs; public uint EFlags; public uint Esp; public uint SegSs; [MarshalAs(UnmanagedType.ByValArray,SizeConst = 512)] public byte[] ExtendedRegisters; } public enum CONTEXT_FLAGS : uint { CONTEXT_i386 = 0x10000,CONTEXT_i486 = 0x10000,CONTEXT_CONTROL = CONTEXT_i386 | 0x01,CONTEXT_INTEGER = CONTEXT_i386 | 0x02,CONTEXT_SEGMENTS = CONTEXT_i386 | 0x04,CONTEXT_FLOATING_POINT = CONTEXT_i386 | 0x08,CONTEXT_DEBUG_REGISTERS = CONTEXT_i386 | 0x10,CONTEXT_EXTENDED_REGISTERS = CONTEXT_i386 | 0x20,CONTEXT_FULL = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS,CONTEXT_ALL = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | CONTEXT_EXTENDED_REGISTERS } [Flags] public enum ThreadAccessFlags : int { TERMINATE = 0x0001,SUSPEND_RESUME = 0x0002,GET_CONTEXT = 0x0008,SET_CONTEXT = 0x0010,SET_@R_785_4045@ION = 0x0020,QUERY_@R_785_4045@ION = 0x0040,SET_THREAD_TOKEN = 0x0080,IMPERSONATE = 0x0100,DIRECT_IMPERSONATION = 0x0200 } [StructLayout(LayoutKind.Sequential)] public struct FLOATING_SAVE_AREA { public uint ControlWord; public uint StatusWord; public uint TagWord; public uint ErrorOffset; public uint ErrorSelector; public uint DataOffset; public uint DataSelector; // missing some stuff public uint Cr0NpxState; } [DllImport("kernel32.dll")] private static extern int VirtualQueryEx(IntPtr hProcess,IntPtr lpAddress,out MEMORY_BASIC_@R_785_4045@ION lpBuffer,int dwLength); [DllImport("kernel32.dll")] public static extern bool ReadProcessMemory(IntPtr hProcess,int lpBaseAddress,byte[] buffer,int size,int lpNumberOfBytesRead);

但由于某种原因,它从来没有击中evt.Exception.ExceptionRecord.ExceptionAddress == address

locking一个文件使用Windows c + + LockFIle()然后从它得到一个stream?

套接字不发送整个内容在Linux(Ubuntu的)

在另一个程序/脚本中实时使用Sysinternals Process Monitor的输出

我怎么能创build窗口站和Windows桌面使用C#

Windows服务Process.Start不在networking服务帐户下工作

我对内存阅读很陌生,很难弄清楚上面的代码有什么问题。

编辑:另外,如果我取消注释context.Dr7 = 0x00000001; 我试图读取应用程序崩溃。

ExternalProject_Add CONfigURE_COMMAND不能包含双引号

想学习大会,困惑从哪里开始

在Linux x64上与x86共享库链接

没有这样的过程 – ptrace

检测Windows进程和应用程序是否正在运行

理论

你想附加一个进程,在其中放置一个断点,在调试器应用程序中注册一个事件并等待该事件。 您需要将断点放在您提供的地址作为参数,通过阅读上下文,您应该可以看到EDX的内容。 这似乎是合理的,就像人类开发者会这样做。

执行:

看看你的实现,你试图用来把断点放在地址的方法似乎是可疑的。 在这里阅读我明白,试图设置运行线程上下文可能会给不可预知的结果。 您也可能缺乏足够的权限。 假设您有权限,请在设置上下文之前尝试停止线程

我预测到一个问题是, 你想停止和调试的线程有一个上下文需要尽可能少地改变 。 我认为你应该先停止线程,读取它的上下文,改变Dr0标志( 假设你在那里设置断点 ),然后设置所有其他寄存器信息不变的上下文。

没有这些,我认为你基本上改变了程序的执行, 我有一种强烈的感觉,那些寄存器是只读的 。

这是你需要考虑的两件事情。 希望能帮助到你。

调试:

如果这不起作用,你需要添加一个函数,使用GetLastError()来看看为什么函数失败(我怀疑Setthreadcontext()将是第一次造成问题的人)。

您还必须检查Context结构是否正确定义,并且所有成员具有与 此处 定义的顺序相同的顺序 。 C#代码中的结构必须与非托管代码完全一致。

另外请检查您是否在64位操作系统上运行。 64位操作系统中的线程上下文与32位不同。 寄存器扩展为64b等等。 如果使用64位操作系统,则需要重新定义上下文结构 。 如果您使用ARM机器,也一样。

你的答案似乎隐藏在你用其他代码移植的一个注释中…设置和获取线程上下文的函数需要一个线程的句柄(可能使用适当的权限打开OpenThread,至少包括get / set上下文)。 相反,你显然是通过一个铸造过程ID。 你应该考虑检查成功的回报值,这可能有助于确定你的问题。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐