Const EM_STREAMOUT = 1098
Const SF_RTF = 2
Const SF_TEXT = 1
Const EM_STREAMIN = 1097
Const SF_UNICODE = 16
Const SFF_PLAINRTF = &H4000
Const MEM_COMMIT = &H1000
Const PAGE_READWRITE = &H4
Public Const PROCESS_ALL_ACCESS As Integer = &H1F0FFF
Public Const PROCESS_VM_WRITE As Integer = &H20
Const INFINITE = &HFFFFFFFF
Public Declare Function WaitForSingleObject Lib "kernel32" Alias "WaitForSingleObject" (ByVal hHandle As Integer, ByVal dwMilliseconds As Integer) As Integer
Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Integer, ByRef lpdwProcessId As Integer) As Integer
Public Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As IntPtr, ByVal lpBaseAddress As Integer, ByRef lpBuffer As Byte, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer
Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByVal lpBuffer As String, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer
Declare Function WriteProcessMemory_EditStream Lib "kernel32" Alias "WriteProcessMemory" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByRef lpBuffer As EditStream, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer
Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Integer, ByVal bInheritHandle As Integer, ByVal dwProcessId As Integer) As Integer
Public Declare Function VirtualAllocEx Lib "kernel32" Alias "VirtualAllocEx" (ByVal hproc As Integer, ByVal lpAddress As Integer, ByVal dwSize As Integer, ByVal flAllocationType As Integer, ByVal flProtect As Integer) As Integer
Public Declare Function CreateRemoteThread Lib "kernel32" Alias "CreateRemoteThread" (ByVal hProcess As Integer, ByVal lpThreadAttributes As Integer, ByVal dwStackSize As Integer, ByVal lpStartAddress As Integer, ByVal lpParameter As Integer, ByVal dwCreationFlags As Integer, ByVal lpThreadId As Integer) As Integer
Public Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Integer
Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal filename As String) As Integer
Declare Function GetProcAddress Lib "kernel32" Alias "GetProcAddress" (ByVal hmod As Integer, ByVal funcName As String) As Integer
'change dll path wherever you put the DLL file
Declare Sub SetText Lib "C:\Program Files\Microsoft Visual Studio\MyProjects\EditStreamCallBack\Debug\EditStreamCallBack.dll" (ByVal str As String)
Declare Function GetAddr Lib "C:\Program Files\Microsoft Visual Studio\MyProjects\EditStreamCallBack\Debug\EditStreamCallBack.dll" () As Integer
Declare Function GetRichTextBoxString Lib "C:\Program Files\Microsoft Visual Studio\MyProjects\EditStreamCallBack\Debug\EditStreamCallBack.dll" () As String
Declare Function GetModuleH Lib "C:\Program Files\Microsoft Visual Studio\MyProjects\EditStreamCallBack\Debug\EditStreamCallBack.dll" () As Integer
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lpEditStream As Integer) As Integer
Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByRef es As EditStream) As Integer
Public Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByVal dest As IntPtr, ByVal source As String, ByVal length As Integer)
Dim hwnd As Integer = &H3B04E2 'handle of the richedit textbox
Dim hproc As Integer
Dim esAddr As Integer
Public Structure EditStream
Public dwCookie As Integer
Public dwError As Integer
Public lpEditStreamCallBack As Integer
End Structure
Public Delegate Function EditStreamCallBackType(ByVal dwCookie As Integer, ByVal buffer As IntPtr, ByVal numBytes As Integer, ByVal cb As IntPtr) As Integer
'injects dll code into (external)target process
Private Sub InjectCode()
Dim pid As Integer
'path to EditStreamCallBack.dll - may vary depending on where you put your dll
Dim path As String = "C:\Program Files\Microsoft Visual Studio\MyProjects\EditStreamCallBack\Debug\EditStreamCallBack.dll"
GetWindowThreadProcessId(hwnd, pid)
hproc = OpenProcess(PROCESS_ALL_ACCESS, 0, pid)
Dim remoteAddr As Integer = VirtualAllocEx(hproc, 0, Len(path), MEM_COMMIT, PAGE_READWRITE)
Dim ret As Integer = WriteProcessMemory(hproc, remoteAddr, path, Len(path), 0)
Dim hmod As Integer = GetModuleHandle("kernel32")
Dim address = GetProcAddress(hmod, "LoadLibraryA")
Dim ret2 As Integer = CreateRemoteThread(hproc, 0, 0, address, remoteAddr, 0, 0)
WaitForSingleObject(ret2, INFINITE)
End Sub
Private Sub Setup()
Dim es As EditStream
InjectCode()
'we are getting the address of the dll function "EditStreamCallBack"
Dim extAddress As Integer = GetAddr
'string we want to write into richtextbox, which includes the RTF keycodes.
'As a final result, it should display "Cplusplus work" in the richtextbox if it works correctly
SetText("{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fswiss\fcharset0 Arial;}}{\colortbl ;\red128\green0\blue0;}{\*\generator Msftedit 5.41.21.2506;}\viewkind4\uc1\pard\cf1\f0\fs20 Cplusplus work\cf0\par}")
es = New EditStream
es.dwCookie = 1 'use 1 if sending EM_STREAMIN or 2 if sending EM_STREAMOUT; reason: thats how our callback function is set up
es.dwError = 0
es.lpEditStreamCallBack = extAddress
'allocate memory for EditStream structure in (external)target process
esAddr = VirtualAllocEx(hproc, 0, Marshal.SizeOf(es), MEM_COMMIT, PAGE_READWRITE)
'write EditStream structure into (external)target process
'reason: When sending EM_STREAMIN to an external app, the external app looks for the EditStream object in its own process.
Dim res As Integer = WriteProcessMemory_EditStream(hproc, esAddr, es, Marshal.SizeOf(es), 0)
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Setup()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'send EM_STREAMIN
SendMessage(hwnd, EM_STREAMIN, SF_RTF, esAddr)
End Sub
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
'send EM_STREAMOUT
SendMessage(hwnd, EM_STREAMOUT, SF_RTF, esAddr)
Dim val As String = GetRichTextBoxString() 'gets the RTF string, which includes the RTF keycodes, in the richtextbox
End Sub
End Class