【问题标题】:Attach debugger and get variable address programmatically Visual Studio附加调试器并以编程方式获取变量地址 Visual Studio
【发布时间】:2020-08-30 15:16:54
【问题描述】:

在使用 C/C++ 编程的微控制器中,所有地址在程序启动之前都是已知的。我可以使用编译时生成的elf文件来查找带有gdb的文件,例如:

gdb "elfFile.elf" -ex "print &variableName" -ex quit

通过向微控制器询问可用于记录和绘制数据的外部工具的变量地址,这对于实时获取变量很有用。该工具从elf文件中获取变量地址,然后只要求微控制器读取地址&variableName处的数据n字节。

我已将一些微控制器代码移植到 Windows 以进行测试,并且它运行正常。我想添加日志功能,为此我需要能够以编程方式从正在运行的 exe 文件中获取变量地址。在程序在 Windows 中启动之前,变量的地址是未知的(也许偏移量是已知的)。我正在使用 Visual Studio Express 2017,我打算获取我自己编译的程序的地址,而不是来自外部的任何程序。在 Visual Studio 中,我可以通过调试器看到任何变量,所以我希望必须有一个调试器 exe 文件,我可以从外部调用并附加到我的程序并以与 gdb 类似的方式读取变量地址。

有什么帮助吗?谢谢

【问题讨论】:

  • 让 Windows 程序将所有相关地址转储到文本文件或类似文件中,首先它会做吗?不管你怎么写,在 Windows 中模拟一个微控制器基本上都是骗人的。特别是,Windows 不存在实时行为。

标签: c++ c visual-studio debugging gdb


【解决方案1】:

您可以使用 CreateRemoteProcess 注入一个 dll,并在那里读取变量地址。

但您正在寻找一个名为OllyDbg 的程序。

另外,您可以下载并安装 MinGW 和 msys,然后您可以从源代码build GDB for Windows。但是你必须在 Windows 上使用 MinGW 来编译程序。 (Mingw 创建本地 Win32/Win64 程序 - 无需 Cygwin)

我没有 CreateRemoteThread 的 C-Sources,但我可以给你 C# 源代码:

// Inject(DLL_NAME, "Engine");
void Inject(string strDLLtoInject, string strEngine) 
{
    CheckIfDebugger();
    //String pszLibFileRemote = Application.StartupPath + "\\"+ strDLLtoInject;            
    //String pszLibFileRemote = Application.StartupPath + "\\"+ strDLLtoInject;            
    //String strPathOfSharedObjectToInject = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + System.IO.Path.DirectorySeparatorChar + strDLLtoInject;
    String strPathOfSharedObjectToInject = m_strTempPath + strDLLtoInject;

    //System.Windows.Forms.MessageBox.Show(strPathOfSharedObjectToInject);
    System.Diagnostics.Process[] TargetProcess = System.Diagnostics.Process.GetProcessesByName(strEngine);

    if (TargetProcess.Length > 0)
    {
        System.IntPtr pTargetProcess = WinAPI.OpenProcess(WinAPI.CREATE_THREAD_ACCESS, false, TargetProcess[0].Id);
        if (pTargetProcess != System.IntPtr.Zero)
        {
            CheckIfDebugger();
            int iLoadLibraryAaddress = WinAPI.GetProcAddress(WinAPI.GetModuleHandleA("Kernel32.dll"), "LoadLibraryA");
            if (iLoadLibraryAaddress != 0)
            {
                int iSharedObjectNameBufferSize = 1 + strPathOfSharedObjectToInject.Length;
                int iSharedObjectNameAddress = WinAPI.VirtualAllocEx(pTargetProcess, 0, iSharedObjectNameBufferSize, 4096, 4);

                if (iSharedObjectNameAddress != 0)
                {
                    CheckIfDebugger();
                    int iReturnValue = WinAPI.WriteProcessMemory(pTargetProcess, iSharedObjectNameAddress, strPathOfSharedObjectToInject, iSharedObjectNameBufferSize, 0);

                    if (iReturnValue != 0)
                        WinAPI.CreateRemoteThread(pTargetProcess, 0, 0, iLoadLibraryAaddress, iSharedObjectNameAddress, 0, 0);
                    else
                        MsgBox("WriteProcessMemory failed.", "Error");

                    CheckIfDebugger();
                } // End if (iSharedObjectNameAddress != null)
                else
                    MsgBox("VirtualAllocEx failed.", "Error");

            }// End if (iLoadLibraryAaddress != null)
            else
                MsgBox("GetProcAddress or GetModuleHandleA failed.", "Error");

            CheckIfDebugger();
            WinAPI.CloseHandle(pTargetProcess);
        } // End if (pTargetProcess != System.IntPtr.Zero)
        else
            MsgBox("OpenProcess failed.", "Error");

        CheckIfDebugger();
    } // End if (TargetProcess.Length > 0)
    else
        MsgBox("GetProcessesByName failed.", "Error");

    CheckIfDebugger();
} // End Sub Inject

这是 WinAPI 调用:

class WinAPI
{
    public const int CREATE_THREAD_ACCESS = 0x1F0FFF;


    [System.Runtime.InteropServices.DllImport("kernel32.dll")]
    public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);

    [System.Runtime.InteropServices.DllImport("Kernel32", EntryPoint = "GetModuleHandleA", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
    public static extern int GetModuleHandleA(string lpModuleName);

    [System.Runtime.InteropServices.DllImport("kernel32", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
    public static extern int GetProcAddress(int hModule, string lpProcName);

    [System.Runtime.InteropServices.DllImport("kernel32", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
    public static extern int VirtualAllocEx(System.IntPtr hProcess, int lpAddress, int dwSize, int flAllocationType, int flProtect);

    [System.Runtime.InteropServices.DllImport("kernel32", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
    public static extern int WriteProcessMemory(System.IntPtr hProcess, int lpBaseAddress, string lpBuffer, int nSize, int lpNumberOfBytesWritten);

    [System.Runtime.InteropServices.DllImport("kernel32", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
    public static extern int CreateRemoteThread(System.IntPtr hProcess, int lpThreadAttributes, int dwStackSize, int lpStartAddress, int lpParameter, int dwCreationFlags, int lpThreadId);

    [System.Runtime.InteropServices.DllImport("kernel32", EntryPoint = "CloseHandle")]
    public static extern int CloseHandle(System.IntPtr hObject);

    // http://www.pinvoke.net/default.aspx/kernel32/GetVersion.html
    [System.Runtime.InteropServices.DllImport("kernel32.dll")]
    public static extern uint GetVersion();

    [System.Runtime.InteropServices.DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, ExactSpelling = true)]
    internal static extern bool IsDebuggerPresent();


} // End class WinAPI

【讨论】:

    猜你喜欢
    • 2018-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多