CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9

Thread: ExtTextOut

Threaded View

  1. #1
    Join Date
    Jan 2011
    Posts
    4

    ExtTextOut

    Hi all. I am using the MS Detours to intercept 4 API functions, DrawText, DrawTextEx, TextOut and ExtTextOut. This is all occurring in a small Unmanaged C++ Dll that I put together (after much Google time, C++ not my forte). From the intercepted functions I call a function that puts together a small COPYDATASTRUCT and ships it off the my main, originating VB.Net app. In the VB.Net app I am retrieving the struct, interpreting and obtaining all text that passes through the target app.

    Everything seems to work like a charm for the two DrawText APIs but not for the two TextOut APIs. First off, whenever I close the VB.Net app (WinForm exe) the target app (ANY app, I have tested on countless programs) crashes whenever I hook the TextOut functions. Secondly, all text retrieved from these functions is completely jumbled. Text is perfect from the DrawText functions, and they do not cause errors or crashes (with the TextOut hooks commented out.

    Can anybody please direct me to what I may be doing wrong? Any help/advice is greatly appreciated as I have spent weeks scouring Google and the web for an answer.

    Code snippets below. Please ask and I will happily provide more info/code.

    TIA

    C++ code:
    Code:
    enum Win32API
    {
        API_TextOut = 1,
        API_ExtTextOut = 2,
        API_DrawText = 3,
        API_DrawTextEx = 4
    };
    
    void TransmitToGUI(int Len, LPCWSTR szText, Win32API sourceAPI)
    {
    	HWND hWnd = ::FindWindow(NULL, L"AutoERP::");
      if (!hWnd)
    	{
        return;
    	}
    	else
    	{
    		if(!szText)
    			return;
    
    		wchar_t Text[255];
    		wcscpy_s(Text, szText);
    
    		COPYDATASTRUCT cds;
    		::ZeroMemory(&cds, sizeof(COPYDATASTRUCT));
    		cds.dwData = sourceAPI;
    		cds.cbData = (Len+1)*2;
    		cds.lpData = &Text;
    		
    		::SendMessage(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds);
    
    	}
    }
    
    BOOL (WINAPI * Real_TextOut)(HDC a0, int a1, int a2, LPCWSTR a3, int a4) = TextOutW;
    BOOL (WINAPI * Real_ExtTextOut)(HDC a0, int a1, int a2, UINT a3, CONST RECT* a4, LPCWSTR a5, UINT a6, CONST INT* a7) = ExtTextOutW;
    int (WINAPI * Real_DrawText)(HDC a0, LPCWSTR a1, int a2, LPRECT a3, UINT a4) = DrawTextW;
    int (WINAPI * Real_DrawTextEx)(HDC a0, LPWSTR a1, int a2, LPRECT a3, UINT a4, LPDRAWTEXTPARAMS a5) = DrawTextExW;
    
    BOOL WINAPI Mine_TextOut(HDC hdc,int X,int Y,LPCWSTR text,int textLen)
    {
      BOOL rv = Real_TextOut(hdc, X, Y, text, textLen);
    	if (text)
    	{
    		TransmitToGUI(textLen, text, API_TextOut);
    	}
    	return rv;
    }
    BOOL WINAPI Mine_ExtTextOut(HDC hdc, int X, int Y, UINT options, RECT* lprc, LPCWSTR text, UINT cbCount, INT* lpSpacingValues)
    {
      BOOL rv = Real_ExtTextOut(hdc, X, Y, options, lprc, text, cbCount, lpSpacingValues);
    	if (text)
    	{
    		TransmitToGUI(cbCount, text, API_ExtTextOut);
    	}
    	return rv;
    }
    int WINAPI Mine_DrawText(HDC hdc, LPCWSTR text,  int nCount, LPRECT lpRect, UINT uOptions)
    {
      int rv = Real_DrawText(hdc, text, nCount, lpRect, uOptions);
    	if (text)
    	{
    		TransmitToGUI(nCount, text, API_DrawText);
    	}
    	return rv;
    }
    int WINAPI Mine_DrawTextEx(HDC hdc, LPWSTR text, int textLength, LPRECT lpRect, UINT uFormat, LPDRAWTEXTPARAMS lpParams)
    {
      int rv = Real_DrawTextEx(hdc, text, textLength, lpRect, uFormat, lpParams);
    	if (text)
    	{
    		TransmitToGUI(textLength, text, API_DrawTextEx);
    	}
    	return rv;
    }
    VB.Net code:
    Code:
    	Public Structure COPYDATASTRUCT
    		Public dwData As Integer
    		Public cbData As Integer
    		Public lpData As IntPtr
    	End Structure
    
    	Friend Enum Win32API
    		API_TextOut = 1
    		API_ExtTextOut = 2
    		API_DrawText = 3
    		API_DrawTextEx = 4
    	End Enum
    
    	<System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _
    	 Protected Overrides Sub WndProc(ByRef m As Message)
    
    		Select Case (m.Msg)
    			Case WM_HOTKEY '// hotkey detected, install hook
    				SetCBTHook()
    
    			Case WM_COPYDATA '// data coming from [API] hook(s)
    				DataReceived(m)
    
    			Case Else
    				MyBase.WndProc(m)
    		End Select
    
    	End Sub
    
    	Private Sub DataReceived(ByRef m As Message)
    		Try
    
    			'// marshal and extract COPYDATASTRUCT from pointer
    			Dim cds As New COPYDATASTRUCT()
    			cds = DirectCast(Marshal.PtrToStructure(m.LParam, GetType(COPYDATASTRUCT)), COPYDATASTRUCT)
    
    			'// if our call, process data
    			If ((cds.dwData >= 1) AndAlso (cds.dwData <= 4)) Then
    				'// marshal and extract string from pointer
    				Dim tms As String = Marshal.PtrToStringAuto(cds.lpData, cds.cbData)
    				'// display text (if present)
    				If (tms.Replace(" ", String.Empty).Length > 0) Then
    					If ((cds.dwData = 1) OrElse (cds.dwData = 2)) Then
    						ListBox1.Items.Add([Enum].GetName(GetType(Win32API), cds.dwData) & ": " & tms)
    						ListBox1.SelectedIndex = ListBox1.Items.Count - 1
    					Else
    						ListBox2.Items.Add([Enum].GetName(GetType(Win32API), cds.dwData) & ": " & tms)
    						ListBox2.SelectedIndex = ListBox2.Items.Count - 1
    					End If
    				End If
    				Else
    					MyBase.WndProc(m)
    				End If
    
    		Catch ex As Exception
    			'MsgBox(ex.Message)
    		End Try
    	End Sub
    Last edited by ovidiucucu; January 14th, 2011 at 06:49 AM. Reason: Corrected [CODE] tags

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured