View Full Version : Hooking text output in a java application

December 3rd, 2008, 12:29
I've written a text hooking application which hooks TextOutA, TextOutW, ExtTextOutA, ExtTextOutW, DrawTextA, DrawTextW, DrawTextExA, DrawTextExW for a target process. It overwrites the apis in gdi32.dll, and user32.dll, (not using the IAT table).

Works fine with most apps. I tried it on a jar file chess program I've got. Ran programme. Hooked javaw.exe - but no results. Apparently none of these functions were being used.

Ran the programme again and attached Ollydbg to the process. Set breakpoints on all the above. None were used. Set breakpoints on PolyTextOut functions. Not being used.

So how does a java programme write text to a window? Whilst Java is cross platform I would assume it would have to end up using the Windows Apis above at some point on Windows - and javaw.exe is the only process I can see.

Used an api spy application and couldn't see text apis being used. Would some of the java dlls be calling direct to win32k.sys? Any input appreciated.

December 3rd, 2008, 15:36
Java has its own text renderer in JVM, so I assume it renders everything internally and displays the whole bitmap.

December 3rd, 2008, 21:31
I think you are right. Somewhere text strings must be internally rendered and output as a graphic. I spent sometime in ollydbg looking at the various java dlls to see if I could see any strings before being internally rendered, and came up with nothing. This might say more about my lack of skill in using ollydbg. It would be nice for the sake of completeness to see where such strings are handled.

December 4th, 2008, 01:40
i dont know jaaahvaaah
just out of curiosity to see if javaw.exe some where uses textout or not i just ran a
oneliner on cdb and it seems awt.dll on the java folder does use textout

here is the oneliner and stack trace when javaw.exe's cronies broke on textout


C:\Program Files\Java\jre1.6.0_07\bin>cdb -c "bp gdi32!TextOutA;bp gdi32!Textout
W;g;kb;q" javaw.exe -jar draw4free.jar
Microsoft (R) Windows Debugger Version 6.10.0003.233 X86
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: javaw.exe -jar draw4free.jar

Executable search path is:
ModLoad: 00400000 00423000 javaw.exe
ModLoad: 7c900000 7c9b0000 ntdll.dll
ModLoad: 7c800000 7c8f4000 C:\WINDOWS\system32\kernel32.dll
ModLoad: 77dd0000 77e6b000 C:\WINDOWS\system32\ADVAPI32.dll
ModLoad: 77e70000 77f01000 C:\WINDOWS\system32\RPCRT4.dll
ModLoad: 77d40000 77dd0000 C:\WINDOWS\system32\USER32.dll
ModLoad: 77f10000 77f56000 C:\WINDOWS\system32\GDI32.dll
(b28.b2c): Break instruction exception - code 80000003 (first chance)
eax=00191eb4 ebx=7ffd8000 ecx=00000007 edx=00000080 esi=00191f48 edi=00191eb4
eip=7c901230 esp=0007fb20 ebp=0007fc94 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
7c901230 cc int 3
0:000> cdb: Reading initial command 'bp gdi32!TextOutA;bp gdi32!TextoutW;g;kb;q'
ModLoad: 7c340000 7c396000 C:\Program Files\Java\jre1.6.0_07\bin\msvcr71.dll
ModLoad: 6d7c0000 6da10000 C:\Program Files\Java\jre1.6.0_07\bin\client\jvm.dl
ModLoad: 76b40000 76b6d000 C:\WINDOWS\system32\WINMM.dll
ModLoad: 6d270000 6d278000 C:\Program Files\Java\jre1.6.0_07\bin\hpi.dll
ModLoad: 76bf0000 76bfb000 C:\WINDOWS\system32\PSAPI.DLL
ModLoad: 6d770000 6d77c000 C:\Program Files\Java\jre1.6.0_07\bin\verify.dll
ModLoad: 6d310000 6d32f000 C:\Program Files\Java\jre1.6.0_07\bin\java.dll
ModLoad: 6d7b0000 6d7bf000 C:\Program Files\Java\jre1.6.0_07\bin\zip.dll
ModLoad: 6d000000 6d12e000 C:\Program Files\Java\jre1.6.0_07\bin\awt.dll
ModLoad: 73000000 73026000 C:\WINDOWS\system32\WINSPOOL.DRV
ModLoad: 77c10000 77c68000 C:\WINDOWS\system32\msvcrt.dll
ModLoad: 76390000 763ad000 C:\WINDOWS\system32\IMM32.dll
ModLoad: 774e0000 7761c000 C:\WINDOWS\system32\ole32.dll
ModLoad: 5ad70000 5ada8000 C:\WINDOWS\system32\uxtheme.dll
ModLoad: 73760000 737a9000 C:\WINDOWS\system32\ddraw.dll
ModLoad: 73bc0000 73bc6000 C:\WINDOWS\system32\DCIMAN32.dll
ModLoad: 74720000 7476b000 C:\WINDOWS\system32\MSCTF.dll
ModLoad: 7c9c0000 7d1d4000 C:\WINDOWS\system32\shell32.dll
ModLoad: 77f60000 77fd6000 C:\WINDOWS\system32\SHLWAPI.dll
ModLoad: 773d0000 774d2000 C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Cont
ModLoad: 5d090000 5d127000 C:\WINDOWS\system32\comctl32.dll
ModLoad: 6d210000 6d263000 C:\Program Files\Java\jre1.6.0_07\bin\fontmanager.d
ModLoad: 6d570000 6d583000 C:\Program Files\Java\jre1.6.0_07\bin\net.dll
ModLoad: 71ab0000 71ac7000 C:\WINDOWS\system32\WS2_32.dll
ModLoad: 71aa0000 71aa8000 C:\WINDOWS\system32\WS2HELP.dll
ModLoad: 71a50000 71a8f000 C:\WINDOWS\system32\mswsock.dll
ModLoad: 662b0000 66308000 C:\WINDOWS\system32\hnetcfg.dll
ModLoad: 58d40000 58d47000 C:\WINDOWS\System32\wship6.dll
ModLoad: 6d590000 6d599000 C:\Program Files\Java\jre1.6.0_07\bin\nio.dll
ModLoad: 6d180000 6d1a3000 C:\Program Files\Java\jre1.6.0_07\bin\dcpr.dll
Breakpoint 1 hitChildEBP RetAddr Args to Child
0304efc8 77d4f0a8 09010fc3 0000001b 00000009 GDI32!TextOutW
0304efe4 77d50af4 09010fc3 0000001b 00000009 USER32!UserTextOutWInternal+0x1a
0304f018 77d509f8 09010fc3 00000030 00000009 USER32!DT_DrawStr+0x11c
0304f04c 77d4f06a 09010fc3 00000009 02ea5380 USER32!DT_DrawJustifiedLine+0x5f
0304f188 77d5095d 09010fc3 00000009 02ea5380 USER32!AddEllipsisAndDrawLine+0x128

0304f234 77d505f0 09010fc3 ffffffff 00000009 USER32!DrawTextExWorker+0x1a1
0304f258 5ad7481a 09010fc3 02ea5380 ffffffff USER32!DrawTextExW+0x1e
0304f2c0 5ad76519 02ea2740 00ffffff 00000001 uxtheme!CTextDraw:rawTextW+0x18c
0304f304 5ad7639c 00010000 09010fc3 00000001 uxtheme!DrawThemeTextEx+0xe0
0304f380 5ad7675c 01010050 00008820 09010fc3 uxtheme!CThemeWnd::NcPaintCaption+0
0304f464 5ad76ab2 00000000 01010050 00000000 uxtheme!CThemeWnd::NcPaint+0x19f
0304f484 5ad71ac7 02ea4ef8 0304f4a0 0304f5a0 uxtheme!OnDwpNcActivate+0x3c
0304f4d4 5ad71b3d 5ad76a76 00000000 00000001 uxtheme!_ThemeDefWindowProc+0x13a
0304f4f0 77d4b9bd 000402f2 00000086 00000001 uxtheme!ThemeDefWindowProcW+0x18
0304f538 77d48709 000402f2 00000086 00000001 USER32!DefWindowProcW+0x6b
0304f564 77d487eb 77d4b1e5 000402f2 00000086 USER32!InternalCallWinProc+0x28
0304f5cc 77d4c00e 00000000 77d4b1e5 000402f2 USER32!UserCallWinProcCheckWow+0x15
0304f5fc 77d4c034 77d4b1e5 000402f2 00000086 USER32!CallWindowProcAorW+0x98
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\P
rogram Files\Java\jre1.6.0_07\bin\awt.dll -
0304f61c 6d073d41 77d4b1e5 000402f2 00000086 USER32!CallWindowProcW+0x1b
WARNING: Stack unwind information not available. Following frames may be wrong.
0304f634 6d07c426 00000086 00000001 00000000 awt!Java_sun_awt_windows_WColor_get

C:\Program Files\Java\jre1.6.0_07\bin>

December 11th, 2008, 09:07
Hey blabberer...do you wear sunglasses when you're composing?

That green text colour you used nearly blinded me.

January 1st, 2009, 17:23
Blabberer - certainly javaw loads gdi32 and with it TextOut etc, but a general java application doesn't use textout (or any other normal api) to draw strings to the screen. This can be seen by 1) a debugger or 2) an api spy or 3) One's own hook.

My guess is that for cross platform compatibility texts are drawn as part of an image which is then drawn to the screen. One would still expect to be able to hook something in say jvm.dll (the java virtual machine). Having spent much time doing this I got zilch. I simply can't find anything in jvm.dll that grabs a known string. There are functions within the jvm that look promising (eg jio_snprintf in jvm or _vsnprintf in msvcr71.dll) - but they don't seem to process my strings.

My reverse engineering isn't particularly hot - but if someone feels like a challenge they could find out where strings are processed in the bowels of java. I've spent many hours on this for quite a few days and I'm beat.


import java.applet.Applet;
import java.awt.Graphics;

public class Where extends Applet{

public void paint(Graphics g) {
g.drawString("Where am I processed in jvm?",50,50);


January 1st, 2009, 20:14
I'd say this: If we're talking about a Java terminal application, the text will absolutely be sent through one of the normal APIs in the end.

Judging from your example though, what we're talking about here is a GUI application, and in this case I wouldn't bother trying to look for any Windows APIs that drawn text will be passing through at all, since it will for sure NOT do this. Rather, it will just use internal Java routines that will interface with the host operating system though the simplest of bitmap graphic interfaces.

Also, the code that draws the text might even be JIT:ed during runtime, which will make it even more troublesome to catch with a normal x86 debugger. If you want to hook these you should decompile the Java application, see which Java APIs it uses for the intended purpose, and then capture these with a hook in the Java JIT engine.