WinAPI EM_STREAMOUT崩溃 [英] WinAPI EM_STREAMOUT crash
问题描述
我正在尝试从另一个程序获取Richedit控件的文本.
I'm trying to get the text of a Richedit Control from another program.
所以我找到了SendMessage的EM_STREAMOUT.
So I found EM_STREAMOUT for SendMessage.
到目前为止,这是我的代码(也来自另一个Stackoverflow主题):
This is my code so far (also from another Stackoverflow topic):
DWORD CALLBACK EditStreamOutCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
std::stringstream *rtf = (std::stringstream*) dwCookie;
rtf->write((char*)pbBuff, cb);
*pcb = cb;
return 0;
}
int main() {
std::stringstream rtf;
EDITSTREAM es = {0};
es.dwCookie = (DWORD_PTR) &rtf;
es.pfnCallback = &EditStreamOutCallback;
SendMessage((HWND) 0x00000000000A06E8, EM_STREAMOUT, SF_RTF, (LPARAM)&es);
}
发生的唯一事情是SendMessage返回0-显然没有读取任何字节-我试图从中获取信息的程序占用了100%的CPU使用率.
The only thing that happens is that SendMessage returns 0 - so obviously no bytes were read - and the program of which I'm trying to get the information out of goes up to 100% CPU usage.
推荐答案
Windows为您封送了某些邮件,例如WM_GETTEXT
.这就是为什么您可以跨过程边界检索窗口的文本. EM_STREAMIN/OUT
不会自动封送.这就是为什么您的代码崩溃的原因. EDITSTREAM
结构和回调代码必须存在于拥有RichEdit的同一进程的地址空间中.
Some messages, like WM_GETTEXT
, are marshaled by Windows for you. That is why you can retrieve a window's text across process boundaries. EM_STREAMIN/OUT
are not auto-marshaled. That is why your code is crashing. The EDITSTREAM
struct and the callback code must exist in the address space of the same process that owns the RichEdit.
对于许多需要跨越过程边界的非封送邮件,可以使用VirtualAllocEx()
分配输入/输出缓冲区,使用WriteProcessMemory()
填充它们,并使用ReadProcessMemory()
从中读取.但是,由于EDITSTREAM
回调代码也需要处于同一进程中,因此最好将整个EM_STREAMOUT
逻辑移到DLL中,然后使用CreateRemoteThread()
或其他注入技术将其注入到目标进程中.您可以使用GetWindowThreadProcessId()
获取拥有RichEdit的进程/线程ID.然后,您的DLL可以检索RichEdit数据,并使用您选择的任何IPC(进程间通信)机制将其发送回您的主应用程序,例如命名管道,邮筒,WM_COPYDATA
消息等.
For many non-marshaled messages that need to cross process boundaries, you can allocate input/output buffers using VirtualAllocEx()
, fill them using WriteProcessMemory()
, and read from them using ReadProcessMemory()
. But because the EDITSTREAM
callback code needs to be in the same process as well, you are best off moving your entire EM_STREAMOUT
logic into a DLL and then inject it into the target process using CreateRemoteThread()
or other injection technique. You can use GetWindowThreadProcessId()
to get the process/thread IDs that own the RichEdit. Your DLL can then retrieve the RichEdit data and send it back to your main app using any IPC (Inter-Process Communication) mechanism of your choosing, such as a named pipe, a mailslot, the WM_COPYDATA
message, etc.
这篇关于WinAPI EM_STREAMOUT崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!