NavigationUser login |
Reversing QT applications - And part IIAnother funny research in QT was this one. After using qtree for one month I realized of some applications building the objects tree in several parts down in stack, so looking for them was too hard that I decided to find another way to locate them.. a Faster way than a tree walktrough. The next step (this one) was to interrupt QT event handler to notify another application when a qt object is receiving an event, so we can react properly to treat that widget. The idea was called qttach, and while attached to a qt application it will dump objects properties when you move the mouse over it. Introduction I'll asume the basics about qwidgets (qt programming). X11, event handling, C++ and gdb skills are also NOT a requisite, as some steps are missing in this explanation. I jumped directly to QT event handling layer (take a look at widget object class for more information). In order to intercept event handling process there are several steps to walk.. QT reversing stuff could be Download from here: qtrev-doc-src.tar.gz How did I get here While in my nights objdumping and gdbing I wrote a txt (actually it's a rtf file full of colours..) about abstracting structures and getting objects properties. This mini-application shows much more information about a widget than explained in previous essay, so if you want to know where did it come from read the "how-did-I-get-here". Anyway, is a good reading for all those "I want to know" or "show me your kung-fu" people, but I think it's a bit hard to follow unless you're in to qt reversing. Focus on event handling When X11 receives an event it sends to any application attached to it's control core. So when you press a button it's not the application who cares first about that event, it's X11 who catch it, and sends the event trough the application tree untill it's processed.< There's then a main control in X11 who cares about events, and there should be another control in QT who receives that event, and coordinated based re-sends again to the correct control (in mouse events, of course). Every time you attach a X11 application you fall into the deepest select() (in select () from /lib/libc.so.6) function, the main event handler of X11 structure, so any try to approach this task (event handling in QT) from here is a long way to hell that you should avoid. Compiled QT applications.. the runtime try to find any *event* match in QT runtime library, using readelf. You will find two interesting function names (private declarations for internal use): QApplication::processNextEvent () from /usr/lib/libqt.so.2 QApplication::enter_loop () from /usr/lib/libqt.so.2 NOTE: to get here, attach a gdb to any qt application, and instead of continue execution try to get out of the "select" loop you are in by setting a breakpoint in the ret of this function. When you reach that ret, use stepi to jump out and (if lucky) you will fall in processNextEvent__12QApplicationb or whatever the libqt you're using had named this function. FYI, processNextEvent is called by enter_Loop function. The way about how the interested widget is in the EDX register is a jump I'll make here. Tracing a little and reading about event handling in QT will show you the arguments of event handling core and how EDX still has the object that reacted with the event, as we are now exiting the event handler (not entering!). x11ProcessEvent__12QApplicationP7_XEvent is a good point of start if you want to investigate here. For now we could be happy, event handler is attached and the object (structure) offset is pointed by EDX register, so dump it for my eyes! qttach application: move your mouse! Every time you attach it to a QT application the first thing to do is to locate the correct libqt version looking for the offset in memory of processNextEvent import. Once located, we breakpoint it (ptrace again) and command the program to continue it's execution. Now, when we keypress, move or click the mouse over a widget, it's data will be displayed in the terminal. Once attached and located the correct offset of the event handler function, qttach enters a loop. When an event is handled, the breakpoint in the process function will advise qttach to show the widget information. It's easier and faster than qtree. Interactive tool will help locate extrange buttons in about or register forms, also, disabled ones, as even if a widget is hidden it's still processing events! Some results (data is dumped from memory): QObject properties.. -memory offset : [0x82c9238]::desktop -unknown 1 : 0x2200 -parent offset : 0x0 -child list at : 0x0 -connections : 0x0 -sender Objects: 0x0 -eventFilters : 0x0 QWidget properties.. -winId : 0x0 -state : 0x4061e420 -flags : 0x3a -position: 0x7a9, 0x0 -size : 0x3ff, 0x2ff -flags : 0x3a -bg color: 0x44495254 - root widgetYes, desktop is another widget for EVERY QT application, it's a root widget. QObject properties.. -memory offset : [0x845f078]::Form1 -unknown 1 : 0x40a462f8 -parent offset : 0x0 -child list at : 0x845f3f8 -connections : 0x8453940 -sender Objects: 0x0 -eventFilters : 0x0 QWidget properties.. -winId : 0x0 -state : 0x406307a0 -flags : 0x4009c9 -position: 0x141a3, 0x220400 -size : 0x257, 0x1df -flags : 0x4009c9 -bg color: 0xc0c0c0 - root widgetConnections from the window (form) are QUIT and basic desktop controls, like hide and so. QObject properties.. -memory offset : [0x845f368]::PushButton1 -unknown 1 : 0x40a44290 -parent offset : 0x845f078 -child list at : 0x0 -connections : 0x0 -sender Objects: 0x0 -eventFilters : 0x0 QWidget properties.. -winId : 0x0 -state : 0x40628fa0 -flags : 0x4009ca -position: 0x7a0, 0x40a46001 -size : 0x64, 0x28 -flags : 0x4009ca -bg color: 0xc0c0c0This button has no connections as it's from a sample application. All this is shown in realtime whenever you move your mouse over the controls, so qttach need to be launched in a terminal window. The list of properties now includes flags, size, position and color, so you can change QT appaerance in runtime also. qstate, Object state runtime modifier. Now that we know the objects memory offset and it's properties, we can play a little further. If we would like, for example to enable a disabled button, we can do it by changing it's state. With a sample application you setup two buttons, and compare their states: Disabled Button: -state : 0x00602807 Hidden Button : -state : 0x00000809 Enabled Button : -state : 0x405ccda0Now, that you now the diferences (some flags are hidden and masking for the paint function) and that you can ptrace the application, you can enable and disable, show or hide, or even modify the connections to functions it has. Trojan qt applications, log passwords keystrokes, own the world is one step ahead!. But I'm not going to release "one button software" for that, source code is old and ugly, idea is even older, and I prefer to code some usefull stuff instead of clean old private code. I had just cleaned three of this programs just for fun, but the rest of the qtreversing library will remain hidden.. and.. lost. Last reading: If you really care about all this I suggest to read the "how did I get here". It was very funny to develop, and also to understand. QT was bigger and complex to reverse than I expected, but that was the point. |
SearchSyndicate |