从调试过程MainModule获取符号 - c#

我开始用C#编写调试器,以调试操作系统上的任何进程。目前,它只能处理断点(硬件,软件和内存),但现在我想显示该过程的操作码。

我的第一次尝试是使用nidsasm(NASM),但这不合适,因为启动后a.Net应用程序汇编程序指令与ndisasm不同(已通过CheatEngine测试)。

因此,我搜索了一会儿,然后从dbghelp.dll中找到了一些方法,可以调用这些方法来列出所有已加载的模块和符号(加上基址)。好的,我的尝试是,使用SharpDisasm分别拆卸所有模块。

我使用ProcessModuleCollection modules = ProcessData.Instance.MPMR.ReadProcess.Modules;获取该进程的所有已加载模块。这很完美。

现在,我尝试加载MainModule的符号,但在这一点上,我坚持使用该实现。我用p / Invoke和其他必要的函数(如SymInitialize)实现了SymEnumSymbols函数。

当我使用BaseAddress(例如“ User32.dll”)调用它时,所有符号均被完美打印,但是对于MainModule,我没有得到任何符号。

这是CheatEngine的屏幕截图:
Symbols gained from Cheat Engine

如您所见,有一些像“ Form1_Load”这样的符号,我的实现中没有。

这是必要的代码示例:

if (!DebugApi.SymInitialize(ProcessData.Instance.MPMR.M_hProcess, null, false))
{
    var err = Marshal.GetLastWin32Error();

    //throw new Exception("GetMemoryInfo failed : GetLastError() : " + new Win32Exception(err).Message);
    Console.WriteLine("GetMemoryInfo failed : GetLastError() : " + new Win32Exception(err).Message);
    return;
}

if (!DebugApi.SymEnumSymbols(ProcessData.Instance.MPMR.M_hProcess, (ulong)ProcessData.Instance.MPMR.ReadProcess.MainModule.BaseAddress, "!", DebugApi.EnumSyms, IntPtr.Zero))
{
    var err = Marshal.GetLastWin32Error();

    //throw new Exception("GetMemoryInfo failed : GetLastError() : " + new Win32Exception(err).Message);
    Console.WriteLine("GetMemoryInfo failed : GetLastError() : " + new Win32Exception(err).Message);
    return;
}

DebugApi.SymCleanup(ProcessData.Instance.MPMR.M_hProcess);

还有我的DebugApi,具有所有必需的p / Invoke函数。

public class DebugApi
{

    [DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool SymInitialize(IntPtr hProcess, string UserSearchPath, [MarshalAs(UnmanagedType.Bool)]bool fInvadeProcess);

    [DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool SymCleanup(IntPtr hProcess);

    [DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern ulong SymLoadModuleEx(IntPtr hProcess, IntPtr hFile, string ImageName, string ModuleName, long BaseOfDll, int DllSize, IntPtr Data, int Flags);

    [DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool SymEnumSymbols(IntPtr hProcess, ulong BaseOfDll, string Mask, PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, IntPtr UserContext);

    public delegate bool PSYM_ENUMERATESYMBOLS_CALLBACK(ref SYMBOL_INFO pSymInfo, uint SymbolSize, IntPtr UserContext);

    public static bool EnumSyms(ref SYMBOL_INFO pSymInfo, uint SymbolSize, IntPtr UserContext)
    {
        Console.Out.WriteLine("Name: " + pSymInfo.Name);
        return true;
    }

    [Flags]
    public enum SymFlag : uint
    {
        VALUEPRESENT = 0x00000001,
        REGISTER = 0x00000008,
        REGREL = 0x00000010,
        FRAMEREL = 0x00000020,
        PARAMETER = 0x00000040,
        LOCAL = 0x00000080,
        CONSTANT = 0x00000100,
        EXPORT = 0x00000200,
        FORWARDER = 0x00000400,
        FUNCTION = 0x00000800,
        VIRTUAL = 0x00001000,
        THUNK = 0x00002000,
        TLSREL = 0x00004000,
    }

    [Flags]
    public enum SymTagEnum : uint
    {
        Null,
        Exe,
        Compiland,
        CompilandDetails,
        CompilandEnv,
        Function,
        Block,
        Data,
        Annotation,
        Label,
        PublicSymbol,
        UDT,
        Enum,
        FunctionType,
        PointerType,
        ArrayType,
        BaseType,
        Typedef,
        BaseClass,
        Friend,
        FunctionArgType,
        FuncDebugStart,
        FuncDebugEnd,
        UsingNamespace,
        VTableShape,
        VTable,
        Custom,
        Thunk,
        CustomType,
        ManagedType,
        Dimension
    };

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct SYMBOL_INFO
    {
        public uint SizeOfStruct;
        public uint TypeIndex;
        public ulong Reserved1;
        public ulong Reserved2;
        public uint Reserved3;
        public uint Size;
        public ulong ModBase;
        public SymFlag Flags;
        public ulong Value;
        public ulong Address;
        public uint Register;
        public uint Scope;
        public SymTagEnum Tag;
        public int NameLen;
        public int MaxNameLen;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]
        public string Name;
    }

}

我的功能应该没问题,因为它可以与其他模块(例如,加载的dll)一起使用。也许我不理解.Net可执行文件符号的概念或缺少某些内容。

参考方案

是否正在寻找System.Diagnostics.SymbolStore.ISymbolScope。
看看类SymbolAccess,您可以使用它访问返回ISymbolVariable []的ISymbolScope.GetLocals()和GetChildren(),这一次再次返回一个称为ISymbolVariable []的数组

现在,另一个有趣的参考代码示例集是Debugger扩展,您可以通过“嗅探”值来显示here

当回复有时是一个对象有时是一个数组时,如何在使用改造时解析JSON回复? - java

我正在使用Retrofit来获取JSON答复。这是我实施的一部分-@GET("/api/report/list") Observable<Bills> listBill(@Query("employee_id") String employeeID); 而条例草案类是-public static class…

从数据表C#创建复杂的JSON - javascript

我的数据集中有3个数据表。表A与B和C有一对多的关系。我想像下面那样在C#中使用Linq创建Json。有人可以帮帮我吗?我要在此先感谢所有将指导我或为我的问题提供投入的人。{ "A": [ { "id": "0001", "type": "donut", &#…

改造正在返回一个空的响应主体 - java

我正在尝试使用Retrofit和Gson解析一些JSON。但是,我得到的响应机构是空的。当我尝试从对象中打印信息时,出现NullPointerException。我确保URL正确,并且我也确保POJO也正确。我正在使用jsonschema2pojo来帮助创建POJO类。这是我要解析的JSON{ "?xml": { "@versi…

每个文件合并后添加换行 - python

我有很多类似以下内容的JSON文件:例如。1.json{"name": "one", "description": "testDescription...", "comment": ""} test.json{"name"…

Json到php,json_decode返回NULL - php

我正在用PHP进行JSON解析器的一些API,用于存储有关遗产的信息。我在解析时遇到问题,因为它返回的是NULL值而不是数组或对象。简单的JSON代码可以很好地解析,但是可以这样:{"success":true,"totalCount":1,"data":[{"id":99694…