3

I'm trying to inject a dll into a software in order to detour it's ExtTextOut function. The injection and detouring works great (I'm using Microsoft Detours), but when I try to modify the ExtTextOut function, everything goes wrong.

Here is my code:

#pragma comment(lib, "detours.lib")

#include <Windows.h>
#include <detours.h>
#include <tchar.h>

BOOL (WINAPI * Real_ExtTextOutW)(HDC hdc, int x, int y, UINT fuOptions, const RECT *lprc, LPCWSTR lpString, UINT cbCount, const INT *lpDx) = ExtTextOutW;

BOOL WINAPI Mine_ExtTextOutW(HDC hdc, int x, int y, UINT fuOptions, const RECT *lprc, LPCWSTR lpString, UINT cbCount, const INT *lpDx)
{
    // The expected results would be that every characters displayed become "z"
    return Real_ExtTextOutW(hdc, x, y, fuOptions, lprc, L"z", 1, lpDx);
}

BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved  )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:

        DetourTransactionBegin(); 
        DetourUpdateThread(GetCurrentThread());

        DetourAttach(&(PVOID&)Real_ExtTextOutW, Mine_ExtTextOutW);
        DetourAttach(&(PVOID&)Real_DrawTextW, Mine_DrawTextW);

        DetourTransactionCommit();
        break;

    case DLL_PROCESS_DETACH:

        DetourTransactionBegin(); 
        DetourUpdateThread(GetCurrentThread());

        DetourDetach(&(PVOID&)Real_ExtTextOutW, Mine_ExtTextOutW);
        DetourDetach(&(PVOID&)Real_DrawTextW, Mine_DrawTextW);

        DetourTransactionCommit();
        break;
    }

    return TRUE;
}

So as you can see in "Mine_ExtTextOut", I'm trying to replace every characters or strings displayed by "z". The result, though, when I try it on various software, looks like this:

http://imgur.com/DI9o3GM (I do not have enough reputation to post image...)

So... why does ExtTextOut draws random characters instead of the letter "z" everywhere?

Ultimately, my goal is to be able to retrieve the text displayed and analyse it in order to know where it's displayed, but I figured starting by being able to modify how it's displayed would be a good start...

MyUsername112358
  • 1,320
  • 14
  • 39

1 Answers1

6

Check the Options on the ExtTextOut call. If they include ETO_GLYPH_INDEX, then the function is expecting glyph indexes (into the font) instead of the actual (Unicode) text. It might just be that 'z' (172) happens to be the index for 'ò' in that font.

Most text drawing functions end up getting processed by Uniscribe and translated ("shaped") into a sequence of font glyphs, which are then rendered to the device context using ExtTextOut with the ETO_GLYPH_INDEX option.

I suspect that if you detour TextOut and DrawText, you'll see more of what you'd expect to see. But that's just a guess. There are lots of functions to draw text (DrawTextEx, PolyTextOut, plus DirectWrite/Direct2D APIs, etc.).

You might have to figure out how to go backwards from glyphs to text.

Adrian McCarthy
  • 45,555
  • 16
  • 123
  • 175
  • I tested it and the ETO_GLYPH_INDEX option is definitely included. On the other hand, TextOut and DrawText are never called... is that normal? Guess I will have to go backwards from glyphs to text, but I've no idea (yet) how to do it :/ – MyUsername112358 Jan 16 '14 at 18:10
  • While searching how to go backwards from glyphs to text (it seems kind of complicated, and even impossible in some scenario), I came with the idea of detouring Uniscribe or ScriptShape instead, could that work? – MyUsername112358 Jan 16 '14 at 18:21
  • 1
    I think what you're trying to do is difficult. Perhaps you should explain _why_ you're trying to do this and we can propose another, simpler way to solve the problem. For example, if you're trying to programatically navigate an application's UI, there are automation APIs. – Adrian McCarthy Jan 16 '14 at 19:06
  • I'm trying to make an application that reads another application and makes calculations given what it read. For instance, if the application displays a value somewhere (health points for example), I want to be able to put that number into a variable and use it into my application (I use file mapping between my application and the injected dll – MyUsername112358 Jan 16 '14 at 19:18
  • 2
    Then I recommend you look at the Windows Automation API, which will let you find text in another application's user interface (among other things). http://msdn.microsoft.com/en-us/library/windows/desktop/ff486375(v=vs.85).aspx – Adrian McCarthy Jan 16 '14 at 20:52
  • +1 on @AdrianMcCarthy 's recommendation to use UI Automation. This sort of thing is exactly what it's for. – Raymond Chen Jan 16 '14 at 21:15