从用户模式 win32 应用程序中可靠地查找当前进程的 _write() 函数的地址
Reliably find the address of the current process' _write() function from a user mode win32 application
我正在编写一个应用程序,它可以从系统上的任何用户模式进程捕获stdout/stderr和调试消息,并将其打印到其控制台。在过去的几个情况下,我一直在编写程序,由于程序的性质,可能是GUI, windows服务等。因为没有控制台,所以无法看到控制台输出。解决这个问题的明显方法是将打印语句更改为调试打印语句,如OutputDebugString()
,然后附加一个调试器并查看输出。有时,设置调试器并查看所需的输出可能会很棘手,特别是在内核模式调试中。
理想情况下,我正在编写的这个应用程序将允许您指定一个PID(最终将处理驱动程序,现在不用担心)-并且无需将应用程序附加为调试器,它将显示用于调试器,标准输出或标准错误的所有输出。
为了做到这一点,我创建了一个应用程序,它将注入一个DLL到系统上的任何进程。从DLL中,我将一个蹦床钩子插入_write()
过程中,从cout、cerr、wcout、wcerr、printf和fprintf捕获用于stdout和stderr的数据。我现在的问题是_write()
过程的地址在每次运行目标应用程序时都会发生变化。目前,我正在windbg中运行目标应用程序,并执行x program!_write
以查找地址,对其进行硬编码并测试我的钩子。
TLDR
当我运行x program!_write
命令时,Windbg如何找到_write()
的地址?我如何从注入到没有符号的目标进程的DLL做同样的事情?
任何帮助都将非常感激。我当前进度的源代码可以在这里找到:https://github.com/vix597/StJude
也如果有一个更好的方法来重定向stdout/stderr从一个注入DLL的目标进程,我洗耳恭听。我尝试过freopen
,但唯一得到重定向的输出是来自注入的DLL本身的输出,而不是注入DLL的应用程序。我是在我无法控制目标应用程序源代码的假设下工作的。我也没有验证_write()
在没有控制台时被调用。
在问这个问题之前,我的测试程序是在静态库中使用MFC编译的。当使用标准的windows库时,Windbg在MSVCR120
中找到_write()
。对于那些试图回答这个问题的人来说,这可能会导致一些混乱,以便更清楚:
无论目标应用程序中的c++运行时是如何编译的,也无论使用的是什么版本的c++运行时环境,我如何找到_write()
方法的地址?
我想要这样写:
LPVOID fnWrite = GetProcAddress(GetModuleHandle(L"<module_name>"),"_write");
关于你关于Windbg如何做到这一点的问题,它使用了Windows的调试API。有了它,你可以插入断点等。具体来说,要在程序中拥有函数的地址,您需要使用dbghelp DLL(您需要有PDB才能工作)。
但是对于您的使用,有一个更简单的解决方案,只要应用程序将运行时作为DLL使用:在该入口点上放置一个钩子。
- boost::进程间消息队列引发错误
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 是否可以通过C++扩展强制多个python进程共享同一内存
- IPC使用多个管道和分支进程来运行Python程序
- 异常属于C++中的线程还是进程
- WMI检测进程创建事件-c++
- 尝试链接我的着色器时,我收到错误代码"error c5145 must write to gl_position"
- c++多进程编写一个唯一的文件
- 如何在C++中将函数发送到另一个进程
- 在Qt Creator中,如何在连接到正在运行的进程后查看控制台输出
- 终止 QProcess 不会终止子进程
- 将返回值从 exe 传递到 bat,并将其传递给 C# 中的进程
- COM :是否可以查看是否存在对我的某个 COM 对象的进程外引用?我可以释放它吗?
- Windows 进程间同步类似事件?
- 在挂钩启动新线程时解除挂钩进程
- pclose() 不会给我进程退出代码
- 运行代码时,c++ 会终止进程
- 可以读入进程内存的最大块大小是多少?
- 枚举进程模块在有效句柄上返回无效句柄
- 如何读取特定地址的进程内存?