Patching VB Applications Using Olly
A discussion around DockLight using some tricks to patch |
| The Target: Docklight 1.6.8 |
| The Tools: Ollydbg 1.10 |
| The Protection: serial check |
Other Information: |
Best viewed in Firefox at 1280x1024
|
1. Introduction |
|
What we will cover here is a number of approaches to handle VB apps, using Olly. VB apps are a little strange for those of you accustomed to C/++ world, due to their "non linear" nature and due to the fact that the call stack is of no usage for Olly users, because the application is continuously inside the VB specific language dlls. This behaviour is common to all those applications using a common language specific dll, such as VB. We will cover how to use Olly to find the correct point where to patch, how to improve disassembled code readability using P32Dasm [1] and MapConv [2] to import MAP symbol files into Olly. The usual approach using Point-h [3] or Point-A [4] is not workign here, due to several problems the application poses. I will use a (classical indeed) trick involving the application's stack to rebuild the calls sequence. have phun.
|
|
1. The Victim Application |
|
http://www.docklight.de/ version 1.6.8 |
|
2. Attacking the application |
||
|
If you launch PEiD you will easily see that the application is written
with VB6 and it's not compressed with a packer. A simple situation then.
Some immediate remarks: method using Point-H doesn't work neither the method called Point-A works. Respectively this happens because the serial is not compared with the way hypotized by Point-H and because the Point-A makes the application stopping too much times, following to interface refresh, making it impossible to obtain anything meaningful. For those of you not knowing these two methods I suggest the two reading in References section below, otherwhise leave them for another occasion, because you will not use them here ^_^ The patch consists simply in finding misleading jmps and then modifiyng them to let the program act as registered.
|
|
3. Inspecting the protection & limits |
|
Keep the things clean and tidy and start from the beginning, looking at
how the program is limited and protected. The limits are: the DockLight Licence Registration which asks for a registration number and several Nags popping out when you try to use a disabled function such as "Save As".
We want to eliminate those limits, but unfortunately the application has been written using another language (VB) for which Olly was not thought to play. OllyDbg is a debugger for compiled languages and works better with languages such as C/C++. VB Applications are fully compiled applications (not relying on a virtual machine such as Java or .NET apps), but have a specific behaviour which get things complicated with Olly.
|
|
4. Some basic concepts about VB apps |
|
Rather than being exaustive, but willing to clarify the approach used here, I would specify some things of VB. All VB programs relies on an external Dll (MSVBVM60.DLL for VB version 6.0 and similar dlls for the other versions, all before VB.NET) which implements all the language APIs and also the event dispachers: the result is that a VB app takes almost all its time inside this Dll or generally goes into it and out of it very frequently. This is a by-design behaviour: being VB a very high language all the VB APIs are implemented into MSVBVM60.DLL. The only thing, almost, that the application owns are the events handlers, used as callbacks from the VB Dll to answer to specific events/messages. The rest of a compiled VB application are the resources, the variables and the functions used to associate events-handlers. The Point-A method [4] just uses a specific point into the MSVBVM60.DLL where the application exits from the Dll to call the application own event handler, using a CALL EAX (where EAX points to the resolved handler). By default, applications created in Visual Basic are compiled as interpreted or p-code executables. At run time, the instructions in the executables are translated or interpreted by a run-time dynamic-link library (DLL) [6]. When used, the p-code engine is a relatively simple machine that processes a series of "high-level" operation codes ("opcodes"). It is stack-based, meaning that it uses the system stack for virtually all its operations. In contrast, an actual microprocessor uses registers for most of its operations and uses the stack primarily to perform function call mechanics. All operands used by p-code instructions are stored on the stack. This behaviour looks very efficient by the language point of view (look also at [6]), because VB programmers essentially will not worry about a lot of things, focusing instead on the specific applications' events and behaviours. But this thing results into a problem for OllyDbg , because the call stack (Alt-K) will not be able to give meaningful answers. For example this is the EP of the application: 004055EC > $ 68
78594000 PUSH Dockligh.00405978 ; ASCII "VB5!6&*" 004055E4 $- FF25
80124000 JMP DWORD PTR DS:[<&MSVBVM60.#100>] ; MSVBVM60.ThunRTMain There are other interesting caracteristics of VB apps which we will use:
This makes difficult to rebuild the call stack, the path the application took to get into a specific place. For example, try placing a BP at this address:
0048C07C . C745 88
10E74100 MOV DWORD PTR SS:[EBP-78],Dockligh.0041E710 (why, will
be clear later), The application stops when you press register.
it doesn't contain a single reference to our application, everything happens inside MSVBM60! Moreover following the call stack and the names of the called VB APIs you can easily follow what I just told you. But, as usual there's a trick I will teach to solve the situation more faster..
|
|
5. Finding HOW to patch the application |
||||
|
Just to get hands on start trying to force the application to accept any
serial you like, popping you the good boy message. Our target now is to force the application to accept any serial, just in case it would be useful. The target is to drive the application to the good boy message. The method is to find the string which is used by the Nag as text of the caption bar and place at that address a Memory BP on Access. From what I told you before it should be clear that that information is read from the form builder inside the VB Dll and used to create the dialog. Now run the application with F9 and wait till it stops at the placed BP.
When the application stops you will have to look at the data stack window (lower righ usually), scrolling it down till you see something as Return to DockList.12314 that's the return address where the whole sequence of VB calls has started. For example search the string "DockLight License Registration" you will find it at 004328C3.
At this point place a Memory Breakpoint on Access at 004328C3 and press F9 to run the application. When you stop you will see in the data stack that the call stack (alt-K) is absolutely useless, but also that there are a lot of returning addresses in the call stack (Olly marks them in red):
Olly mark them in red, also reporting the Activation Record for the calls. What you have to do is to scroll the data stack window down till you see a return addresss into the main application such the following: 0012FC7C |004413F4 RETURN to Dockligh.004413F4 Go at the address 004413F4 and you will see this: 004413EE . FF97
B0020000 CALL DWORD PTR DS:[EDI+2B0] So reasuming we stopped when the VB framework tried to read the string "DockLight License Registration" because of the call at 004413EE. That call is then the original place where the application decided to create the Registration dialog. Go there and you are done (for this little exercise): search the JMP which allows to skip the whole section of code, which in this case is at 00441367. 00441367 . /E9
A0000000 JMP Dockligh.0044140C ;PATCH 1 The initial dialog is nomore called. But this is not a patch indeed, it was just an exercise.. Why this worked?
Using the 2B0 trick The trick consists of:
|
|
6. Finding WHERE to patch the application |
||
|
What we undestood till now is that the VB apps work a little different than usual, that the call stack is useless and why and we also found a way to overcome these limits. The Memory Breakpoint on Access and the data Stack trick is used all along the application and you will have to similarly fix also the other limits as well. I will start slowly to let you test what you learnt and will skip forward the remaining patches to complete the patch. Patch to enable the disabled function The routine at: 004427A0 $ 55 PUSH EBP shows the nag responsible of the "Evaluation Limit". If you analize this call with OllyFlow, or with IDA, you will discover that there's no way out in patching this routine to not show the nag: it's a one way function, so the patch must be in the caller. Go and see where this function is called then. This time we can use normal methods for Olly, then use CTRL-R to find references to this call References in
Dockligh:.text to 004427A0 If you analyze a little you will easily discover that the calling schema is always the same: call function For example this is the situation for Save As 0046D7BF . 8D4D C4
LEA ECX,DWORD PTR SS:[EBP-3C] Unfortunately you can patch the call to return immediately without
doing anything but the test conditions in the calling routine used by
the JMPs are different case by case. Then even if you can do a smarter
patch (and you are invited to try) I chosen to do it quick and dirty
pathing the call and all the JMPs spread in the callers functions. Save Project Note: 0046D7C5 . E8
D64FFDFF CALL Dockligh.004427A0 Patch to accept any serial you insert 0048C02E 6. Active
JNZ Dockligh.0048C0C4 JMP Dockligh.0048C0C4 JMP essentially what I do is to guide the routine: 0048BF60 > \55 PUSH
EBP 0048C30F . FF97
B0020000 CALL DWORD PTR DS:[EDI+2B0] ; Show Licence Agreement Eliminate the string "(Eval)" from the main window's title
|
|
7. Improving code readability using P32Dasm |
|
If you like you can simplify a little your life with Olly and applications
written with other languages than C/C++, inserting the so called MAP
files generated by other decompilers.
Usually these files come from other tools such as IDA or Dede (for Delphi programs, see [5]) or P32Dasm (for VB apps). There is a plugin for OllyDbg called MapConv (by +godfather) [2] which will import those MAP files into Olly as funtion names or comments to disassembled code. Applying such things allows to have a much more readable assembler and definitely to do your work faster.
Among the several VB decompilers we will se P32Dasm (from DARKER -SFC) because its free. Lauch the program and open the Docklight executable. P32Dasm will do its work and write a messagebox with "Done" inside, when finished.
What P32Dasm does is to assign, to all the ASM function it can, a corresponding VB action and it can do this task because knows how the forms data are stored into the exe (remember what I told in Section 4). So this tool practically does a first step in decompilation. But the real usage is in conjunction with a Debugger, because P32Dasm produces only dead-listings. Now select Create MAP file and save the file. After this go into OllyDbg and, using MapConv select "Replace Labels" and "Replace Comments" both. This will insert the items, identified by P32Dasm, as function names for calls and as comments in the disassembly generated by OllyDbg. If you have a runing copy of IDA you can do the same to integrate the two tools, obtaining an extremely readable disassembled code. For example several JMPs become more readable: 0040BCA2 . /E9
69090800 JMP <Dockligh.frmLicence_18.11__(P32Dasm)> All the labels coming from the MAP file are inserted as user comments and user labels so you can review then all into one single window, using the Search For -> User-defined comments function of Olly.
Not everthing is found of course, but you know, better than nothing. For example the jumps table we saw at section 4 at the address 0040BC18 becomes now:
much more clear now! P32Dasm has also an excellent form navigator which should help to find at least a first place where to insert a breakpoint and then combining what P32Dasm tells and the method described here, you should be able to find very fast the point where to patch.
|
|
Conclusions |
|
Obviously there's always a better way to patch an application, I chose
this one because it allowed me to teach you on the call stack trick and
give to you enough examples so as to learn it better. This specific app
can be patched in a more elegant way only changing a single magic byte.
To find how is your next step, but you will have to do it on your own,
as an homework ;-) I will only tell you that magic bytes are very common for VB applications because of the structure of these applications, imposed by the VB common runtime. For further reading on the VB applications I suggest [6] and [7] (in Spanish) Just for knowing it also the other products of this company can be handled with the same approach, and the same "smarter" patch is possible too. Of couse if you plan to use this application professionally or for your work I strongly suggest you to buy it.
|
|
References |
|
I suggest the following further readings from now on to complete this argument..
..and essentially all the tutorials seens around (also others on our tutorials page) which often target checksummed applications.. Just some of the Ricardo Tutorials from CrackLatinos are mirrored on our server
|
|
Greetings |
|
[Nilrem] [Shub-Nigurrath] [MaDMAn_H3rCuL3s] [Kruger] [ThunderPwr] [Eggi] [EJ12N] [Cl0ud] [Gabri3l][Condzero] [Bone Enterprise] Thanks to all the people who take time to write tutorials. Thanks to all the people who continue to develop better tools. Thanks to Exetools, Woodmann, SND, CrackLatinos and all the others for being a great place of learning. Thanks also to The Codebreakers Journal. If you have any suggestions, comments or corrections contact me in usual places..
|