WinAPI EM_STREAMOUT崩溃 [英] WinAPI EM_STREAMOUT crash

查看:162
本文介绍了WinAPI EM_STREAMOUT崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从另一个程序获取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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆