C++ 以编程方式附加调试器并获取变量地址Visual Studio
在使用C/C++编程的微控制器中,在程序启动之前,所有地址都是已知的。我可以使用编译时生成的elf文件来查找带有gdb的文件,例如: gdb elfFile.elf-ex print&variableName-ex quit 这对于实时获取变量非常有用,方法是向微控制器请求外部工具的变量地址,该工具可用于记录和绘制数据。该工具从elf文件中获取变量地址,然后只要求微控制器读取地址处的数据&variableName,共n个字节 我已经将一些微控制器代码移植到Windows进行测试,并且它运行正常。我想添加日志功能,为此,我需要能够从运行的exe文件中以编程方式获取变量地址。在程序在Windows中启动之前,变量的地址是未知的,但偏移量可能是已知的。我正在使用Visual Studio Express 2017,我打算获取我自己编译的程序的地址,而不是来自外部的任何程序。从VisualStudio内部,我可以看到任何带有调试器的变量,所以我希望有一个调试器exe文件,我可以从外部调用并附加到我的程序中,以与gdb类似的方式读取变量地址C++ 以编程方式附加调试器并获取变量地址Visual Studio,c++,c,visual-studio,debugging,gdb,C++,C,Visual Studio,Debugging,Gdb,在使用C/C++编程的微控制器中,在程序启动之前,所有地址都是已知的。我可以使用编译时生成的elf文件来查找带有gdb的文件,例如: gdb elfFile.elf-ex print&variableName-ex quit 这对于实时获取变量非常有用,方法是向微控制器请求外部工具的变量地址,该工具可用于记录和绘制数据。该工具从elf文件中获取变量地址,然后只要求微控制器读取地址处的数据&variableName,共n个字节 我已经将一些微控制器代码移植到Windows进行测试,并且它运行正常。
有什么帮助吗?谢谢您可以使用CreateRemoteProcess插入dll,并在其中读取变量地址 但是你正在寻找一个叫做 此外,您还可以下载并安装MinGW&msys,然后可以从源代码处下载。但是你必须在Windows上使用MinGW来编译程序。Mingw创建本机Win32/Win64程序-无需Cygwin 我没有CreateRemoteThread的版本,但我可以提供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
Windows程序是否首先将所有相关地址转储到文本文件或类似文件中?不管你怎么说,在Windows中模拟微控制器基本上都是骗人的。特别是,Windows不存在实时行为。