You are on page 1of 34

REVERSING THE PROTECTION SCHEME OF HELLRAISER SYSTEM UTIL V4 CRACKME IN ??

MOVES BY GYVER75
FOREWORDS
Crackmes.de is probably the most important site where a novel reverser can test his abilities: little programs written in different languages (C, Delphi, Assembler, Visual Basic etc...) just expect us to be solved. Clearly, every Crackme has a different difficult level; personally I choose a level # 8 crackme for three principal reasons: 1) Curiosity: Ive never reversed this type of target: Because is it so hard? Will I be able to solve it? Probably both.. 2) Challenge: isnt it a real challenge to try discovering some weakness behind a protection scheme? 3) Increasing my knowledge: my Baskets coach said: even just playing with stronger men, you can learn something! With this spirit, I solved the HellRaiser System Util V4; the scope is simply unpack the target and find the right serial to unlock the buffer slider of its form. Indeed, because this CrackMe has not yet a solution, I decided to write this little paper... so I hope youll have a good leisure and as always, sorry for my bad English (thanks to Shub for his review)!

1.1

TABLE OF CONTENTS

Forewords ....................................................................................................................................................... 1 1.1 1.2 1.3 Table of Contents ................................................................................................................................. 1 Tools used ............................................................................................................................................ 2 Second step: Studying the Pe structure ................................................................................................ 3

1.4 First Step: playing with the target ........................................................................................................ 4 1.4.1 Some infos about hellrAiser.fms.exe .................................................................................................. 7 1.4.2 Some infos about fastcopy.tmp ........................................................................................................ 10 1.5 Third step: Crash analysis of fastcopy.exe and relationship between fastcopy.tmp and hellrAiser.fms.exe .......................................................................................................................................... 12 1.6 1.7 Fourth Step: Study of Visual Basic targets reversing ........................................................................... 17 Fifth step: Find the secret inside fastcopy fixed.exe ........................................................................... 17

HELLRAISER SYSTEM UTILITY V4 REVERSING


1.8 1.9 1.10 1.11 Conclusions ........................................................................................................................................ 33 Errata Corrige ..................................................................................................................................... 33 References ......................................................................................................................................... 34 Greetings ............................................................................................................................................ 34

1.2

TOOLS USED
A ring 3 debugger: its a real challenge to discover a working alternative to OllyDbg , its the most famous and probably powerful ring 3 debugger available on Microsoft Operative Systems; its free and extensible with many plugins. Personally, in my Ollydbg copy, I installed these ones: o Scherzos LCB plugin: Useful to import / export Labels, Comments and Breakpoints into / from a file; in this way you will never miss any data under Olly; o OllyVbHelper plugin: Find and label DllFunctionCall and MSVBVM imports; o Stealth64 1.2 beta plugin: dont misunderstand me, i dont like use plugins to hide the presence of OllyDbg, in particular way when we play with these targets, but i suggest you to use this plugin if you have a O.S 64 bit. In this case, do it: Plugins -> Stealth64 -> Options -> [Misc] check x64 compatibility mode! o ODbgScript plugin: in reality we will never use this plugin with this target but its really a MUST! A Pe File Analyser: in order to take some infos on sections, Dlls and functions used by the Victim, this type of tools is mandatory; I prefer CFF Explorer VII with Resource Tweaker plugin installed; Import REconstructor 1.7c: useful to automate the reconstruction of Import Address Table partially or totally destroyed; Process Explorer v12 and Process Monitor v 2.8: sysinternals tools useful to play with our Crackme; Comdlg32.ocx: probably if you will try to reverse this target under Windows 7 / Vista, you will need this file. Because Microsoft developed only a 32 bit version of this component, to install this one under 64 bit O.S, you must do: o Copy the file in %Systemroot%\SysWOW64 ( System32 for 32 bit O.S ); o Type in Cmd: regsvr32 %Systemroot%\SysWOW64\ComDlg32.ocx ; Brain: its really needed for this kind of passions !

HellRaiser System Util V4 reversing

HELLRAISER SYSTEM UTILITY V4 REVERSING

1.3

SECOND STEP: STUDYING THE PE STRUCTURE

Thanks to CFF Explorer, we have other information (see Figure 1):

Figure 1. hellrAiser.Fms4.exe is compressed with the famous and the ... most simple UPX packer!

Well, if theres someone here who doesnt know how unpack an UPX packed target please raise your hand! Personally, I used UPX Utility inside the CFF Explorer and what I got is an unexpected result (see Figure 2):

Figure 2. hellrAiser.Fms4.exe is a RAR archive!

Nice, our Crackme is indeed a self-extracting RAR archive packed with UPX! So the next step is really simple: use WinRar or 7Zip to open the archive.

HellRaiser System Util V4 reversing

HELLRAISER SYSTEM UTILITY V4 REVERSING

Figure 3. Result of 7Zip operation.

Bingo! We found fastcopy.tmp without any problem! Till there it was really a simple thing, but also a quite easy method to create a loader, without coding a thing. Indeed we could get to this same conclusion also using the utility Process Monitor by Sysinternals. This tool, as its name clearly states, monitors the activity of every Process\Thread. What we do is to add a filter which instructs the application to only monitor our target and inspect its File system activity. We can see that two interesting entries soon appear:

Figure 4. Snapshot of Process Monitor when it scans the activity of hellrAiser.Fms4.exe.

We therefore know that our target extracts its 2 files into c:\temp! On the other hand the bad news is that now we have a couple of files to investigate instead just one: double work, means twice the compensation? We will see ..

1.4

FIRST STEP: PLAYING WITH THE TARGET

If you have already read my previous tutorials (available on ARTeam web site), you should know how important is this stage; after loading the Crackme, push any buttons of the interface, enter as many serials as possible and try to understand how the target reacts! In other words you must manually fuzz the program in order to find few good attack points. Figure 5 clearly reports what I did to play with the proggie:

HellRaiser System Util V4 reversing

HELLRAISER SYSTEM UTILITY V4 REVERSING

Figure 5: Searching some good point of Attack

Note that all the assumptions you can do must be verified, anyway the most important thing is to understand the structure of the target in order to discover some weakness! Another idea is to launch the Crackme and look how it works, for example using Process Explorer v1.2. Doing this we can understand if its a multithreaded program or simply a loader (a program that creates a new child process which is executed in turn when the father dies) . I was indeed quite surprised to realize that for this crackme this was case, a loader. Indeed, if we start the target and monitor it with Process Explorer (File -> Run -> Name of Program) the following events occur:

HellRaiser System Util V4 reversing

HELLRAISER SYSTEM UTILITY V4 REVERSING


1. 2. 3. In the Processes view, as a son of the process Procexp.exe, you can find the process hellrAiser.Fms4.exe (Child process); If you continue looking at the processes list, after a little delay, a second Process appears in the root level of Processs Tree (no Parent Process), which is called fastcopy.tmp; The hellrAiser.Fms4.exe process is therefore terminated;

The final result is better explained in the Figure 6:

Figure 6. The hellrAiser.Fms4.exe is simply a loader, the real target is fastcopy.tmp.

At this stage it should be quite evident that, inside hellrAiser.Fms4.exe we will need to hook the calls to functions like CreateProcess and ResumeThread and only inside fastcopy.tmp we will search APIs like MessageBox and GetDlgItemText. Indeed, a good reverser should ask himself: Where are stored the raw data that will belong to the new Process? Are they in a particular section inside the PE structure of the father process or simply generated by this last one, for example allocating a memory block and filling it with some Hex values? The typical lifecycle of loaders such these (which are also called droppers) is to execute a piece of code that creates and allocates a new buffer, then fill it with some blob data (which are blob by the loaders point of view), eventually decrypted them, and finally, just before terminating, turn the execution handle to that buffer. In order to gather details to answer these questions, we will do a deeper analysis, beginning from the PE structure.

HellRaiser System Util V4 reversing

HELLRAISER SYSTEM UTILITY V4 REVERSING

1.4.1 SOME INFOS ABOUT HELLRAISER.FMS.EXE


Thanks to CFF Explorer, we can see that this executable is again compressed with UPX packer:

Figure 7. Another section ( yoda ) is created from previous unpacking operation.

I would point your attention to the Figure 7, the loader differs from the previous packed rar file due to the presence of a new section called yoda. How the loader uses data inside this section will be explained later; now its important unpack again the target to have a clear vision of all things so far. So: 1. 2. 3. 4. 5. fire up OllyDbg; go down to the last jump instruction before a zero padded area; put here a Hardware Breakpoint and press Run; whenever the program stops, remove the breakpoint and execute the jump instruction (F7); now we are ready to dump the final unpacker destination and fix the import table;

See the figure below to better understand:

Figure 8. Essential steps to discover the Entry Point of a UPX target!

HellRaiser System Util V4 reversing

HELLRAISER SYSTEM UTILITY V4 REVERSING


Probably a newbie reverser could ask: Why are you so sure that address 0x4018A0 is the real entry point of unpacked executable? The answer is quite simple: Experience!; the presence of Prologue code ( 0x55, 0x8B, 0xEC opcodes ) or the correct link to Kernel32.GetVersion at the offset 0x4018C6 are good hints ( both th are underlined in green in the 5 snapshot inside Figure 8 ) but the Entry Points study of samples written with different compilers is surely the best choice to recognize where we must to stop and then, dump (I remember that Evolution wrote an ExeCryptor tutorial with this approach ! )! The 2 important thing to do ( the 1 one was to find the OEP) is to repair the Import Address Table; so, leaving in background our Ollydbg, open Import Reconstructor v1.7c and follow these steps: 1. 2. 3. Attach the Active Process hellrAiser.fms.exe; in reality, this target is in suspend state under OllyDbg at the address 0x4018A0; In the Area Imported Functions Found press Mouses Right Button -> Advanced Commands -> Select Code Section(s) -> a new dialog will appear in front of you and push Full Dump button; name the new file ( i.e hellrAiser.fms_.exe );
nd st

Good, you have now a full dump of target! All modifications will be saved here! In IAT infos Needed box, we must to change 3 parameters: Entry Point, Import Address Table and its Size;

Figure 9. IAT Infos Box.

As you can see in the figure above, I underlined that every offset is relative to the address of target loaded in memory (Image Base Address); the PE header suggests to the O.S. loader the file should be loaded in memory; most executable anyway simply dont ask anything special to the O.S., so the offset automatically assigned by Window is 0x400000. Anyway go with the process and find all the information needed by ImpRec. 4. 5. In the OEP edit control, enter: 0x18A0; ( Relative Virtual Address = Virtual Address Image Base Address -> 0x18A0 = 0x4018A0 0x400000 ) To find the relative virtual address of Import Table, we can use OllyDbg: do you remember the offset 0x4018C6 in the Figure 8, marked in green? At this address Olly recognizes a pointer to Kernel32.GetVersion Function; this means that address belongs to the Import Address Table! So, if we press here the Mouses right button and select: Follow in Dump -> Memory Address we land in this memory area:

HellRaiser System Util V4 reversing

HELLRAISER SYSTEM UTILITY V4 REVERSING

Figure 10. IAT in OllyDbg!

It should be quite clear which values to assign to the last two data requested by ImpRec, Figure 9 helps to understand that RVA = 0x5000 and Size = 0xC8. 6. now turn back to ImpRec and press Get Imports and check the result, this time all the imports are correctly fixed so what is left is to push the button Fix Dump. Import Reconstructor will create a new section (. TiGa) in the dump file and the new Import Table will be fixed!

These are all steps needed to unpack an UPX target (I just used to long way for the sake of clarity with beginners); the final result could be seen with CFF explorer:

HellRaiser System Util V4 reversing

HELLRAISER SYSTEM UTILITY V4 REVERSING

Figure 11. PE structure of our unpacked file: hellrAiser.fms first layer.exe!

Clearly, the previous steps were not meant as a general guide for unpacking but rather as a specific sequence of steps used to create a working dump of this crackme, with a simple packer like UPX. Into the ARTeam tutorials section there are plenty of deeply detailed tutorials on how to unpack or write unpackers.

1.4.2 SOME INFOS ABOUT FASTCOPY.TMP


From our previous analysis, we know that fastcopy.tmp is indeed an executable; to proof it we simply open an Hexadecimal editor and look the early bytes where the DOS Stub loader is clearly visible:

Figure 12. First bytes of fastcopy.tmp.

HellRaiser System Util V4 reversing

10

HELLRAISER SYSTEM UTILITY V4 REVERSING


So, why dont change the .tmp extension in .exe ?

Figure 13. Result of files extension change.

The first logic thing to do is to verify if our new file, fastcopy.exe, is really working because, in case of success, we can simply discard the loader (hellrAiser.Fms.exe) and consider only this last one! Unfortunately, after loading fastcopy.exe, Windows (I have an O.S Italian copy, so every systems message will be written in Italian language!) notify us a Crash of the application:

Figure 14. fastcopy.exe is not independent by its loader!

What a pity! Moreover, if we dont rename fastcopy.exe in c:\temp, the loader hellrAiser.fms.exe will stop to work otherwise it will remain in memory (it simply monitors the presence of a process called fastcopy.tmp before dying):

Figure 15. hellrAiser.fms.exe (no WINDOWS!) notify the absence of fastcopy.tmp with an Error Message!

As before experience drives us to do an hypothesis of why the dumped and fixed file is not loading properly. What we found is that the loader creates the process from fastcopy.tmp, therefore it changes some bytes in the child memory space and just after invokes the function ResumeThread! This is a technique used by several wrappers, even commercial like that used by Popcap Game and Reflexive. Of course also this hypothesis must be verified!

HellRaiser System Util V4 reversing

11

HELLRAISER SYSTEM UTILITY V4 REVERSING

1.5

THIRD STEP: CRASH ANALYSIS OF FASTCOPY.EXE AND RELATIONSHIP BETWEEN FASTCOPY.TMP AND HELLRAISER.FMS.EXE

Before to fire up our favourite debugger OllyDbg and to discover why fastcopy.exe crashes, we can add some details using the Window O.S Events Viewer. Indeed, using this tool we can understand the error and the offset (Relative Virtual Offset) where it was generated: Error Type: 0xC0000005 alias Memory access violation; Error Offset Occurred: 0xF89E;

Other additional information comes from analysis of PE structure (again thanks to CFF Explorer):

Figure 16. PE structure of fastcopy.exe

The figure above clearly shows that also fastcopy.exe (and so fastcopy.tmp) is compressed with UPX. Indeed, the Entry Point (marked in green) is really near to the address where the Memory access violation occurs; so we can suppose that the crash happens in the unpacking phase, at the virtual offset 0x40F89E (Image Base Address + Relative Virtual Address). We have therefore a precise hypothesis to verify and we can now open OllyDbg to check what happens.

HellRaiser System Util V4 reversing

12

HELLRAISER SYSTEM UTILITY V4 REVERSING

Figure 17. fastcopy.exe is an malformed UPX target!

From the figure above, its now clear why fastcopy.exe crashes: it tries to execute the instruction: ADD BYTE DS:[EAX], AL where EAX references a protected memory area !

Because the last typical JMP of any UPX target has been removed, and not yet restored. You should already understand what the father process does to its son in order to make it running.. To solve this problem and understand how the loader changes the target, we can launch 2 OllyDbg sessions, one for hellrAiser.fms.exe (remember! In the same folder fastcopy.tmp must to be present) and one for st nd fastcopy.exe. We will anyway just use the 1 Olly meanwhile the 2 Olly will help us simply better see the patches applied into the child process. With this experimental setup we start to analyze all the intermodular calls of the father loader:

HellRaiser System Util V4 reversing

13

HELLRAISER SYSTEM UTILITY V4 REVERSING

Figure 18. All intermodular calls in the loader hellrAiser.fms.exe.

Of course there are two expected calls to WriteProcessMemory. Using the Win32 SDK reference we find: The WriteProcessMemory function writes memory in a specified process. The entire area to be written to must be accessible, or the operation fails. Its prototype is: BOOL WriteProcessMemory( HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesWritten ); So we set a breakpoint for each call to WriteProcessMemory and therefore press F9 inside Ollydbg. The result is that Olly land us here: // handle to process whose memory is written to // address to start writing to // pointer to buffer to write data to // number of bytes to write // actual number of bytes written

HellRaiser System Util V4 reversing

14

HELLRAISER SYSTEM UTILITY V4 REVERSING

Figure 19. Snapshot of the patching task of fastcopy.tmp process!

In this picture, i wanted underline the heart of the patching done by hellrAiser.fms.exe. The loader invokes VirtualProtectEx for each byte it needs to modify inside its son and sets the read and write permissions (into the Process handler 0x58, alias fastcopy.tmp). After this step the API WriteProcessMemory is used. This portion of code belongs to a loop which has as counter the number of bytes needed to modify. The loader knows the addresses and the values to change, see the figure below:

Figure 20. The importance of yoda section inside the loader!

HellRaiser System Util V4 reversing

15

HELLRAISER SYSTEM UTILITY V4 REVERSING


It is now clear what the section yoda was meant for; here there is an array of 6 records and every record has 4 fields like below:

RECORD FIELDS

Fastcopy.tmp offsets to patch

Number of bytes to patch each time

Old Bytes

New Bytes

This discovery can be used to do the patches into fastcopy.exe manuall. We can restore the last jump instruction inside the UPX0 section (JMP fastcopy.0040155C) and then finally unpack it! The final result is in the picture below:

Figure 21. unpacked fastcopy.exe !

Finally we have a working dumped and unpacked program which doesnt anymore need its loader. We can finally throw away the loader hellrAiser.fms.exe and reverse the new fastcopy fixed.exe!

HellRaiser System Util V4 reversing

16

HELLRAISER SYSTEM UTILITY V4 REVERSING

1.6

FOURTH STEP: STUDY OF VISUAL BASIC TARGETS REVERSING

Yes, I generally speaking suggest to take a look at papers describing how to revere VB applications, such like VB Reversed A decompiling approach by Andrea Geddon. The risk to get lost inside the VB virtual Machine is quite high! There are also some documents posted in the ARTeam forum by CodeRipper which are very useful to understand some important VisualBasic APIs.

1.7

FIFTH STEP: FIND THE SECRET INSIDE FASTCOPY FIXED.EXE

Do you remember the hypothesis done about the presence of some API like MessageBoxA and GetDlgItemTextA (see the Figure 1)? Well, these functions are really invoked but not directly; indeed our target will call only VB APIs and only therefore Win32 APIs will be invoked by msvbvm60.dll, alias Visual Basic Virtual Machine!

Figure 22. How Visual Basic Virtual Machine works with the APIs.

So, if we dont want to reverse also msvbvm60.dll, we are obligated to learn something about Visual Basic APIs, particularly how the parameters are passed and which CPU registers are used as input and output!

Figure 23. VB functions seen like SISO systems !

To be honest, quite often the reversing approach shown in Figure 23 is what we use; how many times you pressed F8 (alias Step Over) over a MessageBoxA call? This black-box approach is quite common while reversing. We usually often just need to understand: 1. the instructions used to pass parameters to the function (especially if the application is written in C/C++); HellRaiser System Util V4 reversing 17

HELLRAISER SYSTEM UTILITY V4 REVERSING


2. 3. what this function does; the SDK could help! which register are used to store input and output!

So, the only difficulty is just to know what the VB APIs does; luckily their Names are quite self-explanatory! The 2 thing needed to reverse our target, is the concept of Variant type variable; doing a comparison, an array variable is a single type multi value meanwhile a Variant object is a multi type single value From a coding point of view, a Variant object is a structure of 16 bytes, organized in 3 fields:
1 Field 2 Field 3 Field
nd

0x00 byte

0x01 byte

0x02 byte

0x03 byte

0x04 byte

0x05 byte

0x06 byte

0x07 byte

0x08 byte

0x09 byte

0x0A byte

0x0B byte

0x0C byte

0x0D byte

0x0E byte

0x0F byte

Type

Generally unused

The Data Variant object contains

The 1 field, marked in orange, describes the type of the Variant variable; in the following table I highlighted the most used type values:

st

Type Name
Empty

Internal Type Name


VT_EMPTY

Hex Value
0

Null

VT_NULL

Error / Missing

VT_ERROR

0x0A

Boolean

VT_BOOL

0x0B

Int

VT_I2

Long Int

VT_I4

Single Real

VT_R4

Double Real

VT_R8

String

VT_BSTR

Array

VT_ARRAY

0x2000

Reserved

VT_RESERVED

0x8000

HellRaiser System Util V4 reversing

18

HELLRAISER SYSTEM UTILITY V4 REVERSING


Table 1. Some Types of Variant Objects.

So, thanks to this table, we can do some example about the initialization of the memory area reserved to the different types of variant objects:
0x02 0x00 ------0x03 0x00 -------

Example 1. Variant Object of Int type initialized to 3; only the first 2 bytes ( 8- 9 ) of 3 field are used.

0x03

0x00

--

--

--

--

--

--

0x03

0x00

0x00

0x00

--

--

--

--

Example 2. Only first 4 bytes of 3 field are used by a Variant Object of Long Int type, initialized to 3.

0x02

0x20

--

--

--

--

--

--

Arrays offset (32 bit)

--

--

--

--

Example 3. Variant Object of Int Array type. The Type field is obtained by an OR operation: VT_ARRAY VT_I2.

0x0A

0x00

--

--

--

--

--

--

0x04

0x00

0x00

0x00

0x02

0x00

0x00

0x08

Example 4. Missing Variant Object; to differentiate itself from Error Variant Object (same type), has the 3 field initialized to the value 0x8002004!

With these considerations, we can start to reverse our target but, first of all, I highly recommend you to LOAD MY OLLYDBG COMMENTS AND BREAKPOINTS THROUGH LCB SCHERZO PLUGIN (you can find them inside the LCB TXT folder distributed with this tutorial); doing this way it will be definitely easier for you to follow my explanations. If you remember the hypothesis done in Figure 1, we must search a piece of code with the pattern: MessageBox -> DialogBox -> Some Calculation ... -> MessageBox of God / Bad Guy Clearly what we should understand is which is the Visual Basic s APIs that invokes the Win32s MesageBox. If you have read the documents posted by CodeRipper in ARTeam Forums, you shouldnt find it difficult (its anyway even simple to do it on your own backtracing the stack up to an msvbvm60.dll export). Therefore using OllyDbg we will search the intermodular calls to rtcMsgBox and rtcInputBox respectively.

HellRaiser System Util V4 reversing

19

HELLRAISER SYSTEM UTILITY V4 REVERSING

Figure 24. Intermodular Calls of Fastcopy fixed.exe.

We are lucky because there is only an offset (0x406ED0) where the target invokes rtcInputBox; so, we can simply put a Breakpoint here and run the program being sure that its the right place where to start our analysis. Indeed, as you can see in between the yellow marked lines above, there is a reference (0x406DEE) to a rtcMsgBox near a call to rtcInputBox; this should help you to distinguish among the different calls, because after the request for new input (done through rtcInputBox) the program shows the message (through rtcMsgBox). Our analysis begins few lines above the address 0x406DEE:

Figure 25. Low level analysis about calling of VB function: rtcMsgBox.

From the figure above, we can understand that the VB function rtcMsgBox receives 5 parameters, all of them are Variant Variables. These objects are created in to the Stack; EAX and EBX registers are initialized to build Missing Variant Objects meanwhile EDX register points to Integer Variant, that will be used as text inside the MessageBox. The most important thing to remember is that, for each Variant variable, there is a double initialization: one for its Type and one for its Value! After all the Variant are structures and its members must be initialized one-by-one.

HellRaiser System Util V4 reversing

20

HELLRAISER SYSTEM UTILITY V4 REVERSING


After a push to the OK button on the program interface, the program frees some Variant Objects through the vbaFreeVarList Function; its prototype is: vbaFreeVarList(Number of Variant variables to free, 1st Variant, 2nd Variant,...) Its interesting to underline, using following figure, that this function indeed doesnt free stacks ports (for example incrementing the ESP register) but it simply marks as empty the Variant Objects allocated by the API:

Figure 26. How works the vbaFreeVarList Function; the Subtype of Variant objects to free is marked as VT_EMPTY.

After this piece of code, the target prepares itself to invoke the rtcInputBox function: it has 7 parameters, each of these is, again, a Variant variable; the following picture shows how these objects are created:

Figure 27. Initialization of 7 Variant Objects before to call rtcInputBox function.

The EAX and EBX registers are used, respectively, to initialize the SubType (VT_ERROR = 0x0A) and Value (02000480) of Missing Variant Variables; the first two parameters are UNICODE String Variant Variables used as caption and text of the InputBox form. These last ones are built through vbaVarDup(Dest,Source) function:

HellRaiser System Util V4 reversing

21

HELLRAISER SYSTEM UTILITY V4 REVERSING

LEA EDX, Source Stack Offset; LEA ECX, Destination Stack Offset; Initialization of Source; CALL vbaVarDup;

Table 2. Low level code before to call vbaVarDup function. This routine simply duplicate Source parameter in Dest one.

After having created all the parameters, this Crackme is ready to invoke the rtcInputBox routine:

Figure 28. rtcInputBox( Text, Caption, Missing, Missing, Missing, Missing, Missing ) function.

The returns value of the routine above is simply the input we entered through the GUI; being a UNICODE String its offset is stored in EAX register. At This point, the program creates a String Variant Object initialized with our serial and moves it in a New Variant variable through vbaVarMove function:

Figure 29. vbaVarMove( Dest, Source ) function.

At this point, the program frees the Stacks ports reserved for the parameters of rtcInputBox function (in st nd other words it executes the CALL vbaFreeVarList( 7, 1 param, 2 param, ... )) and therefore starts a classic check on Serials length: Serial Length = vbaLenVar(String Variant Object); If vbaVarTstNe(Serial Length, 0) == 0 Then Bad Boy Message; If vbaVarTstEq(Serial Length, 9) != 0 Then Bad Boy Message;
Table 3. Tests about the length of the serial.

The two Boolean functions, used to test the Serials Length, compare Variant Variables; for this reason the Serials Length is a Long Int Variant object ( SubType = VT_I4 ) meanwhile constant integers 0 and 9 are the Values of New Int Variant objects with SubType = VT_RESERVED or VT_I2. The first routine tests if Serial

HellRaiser System Util V4 reversing

22

HELLRAISER SYSTEM UTILITY V4 REVERSING


Length IS NOT equal to 0 meanwhile the second compares if Serial Length IS equal to 9... remember, the logic value FALSE corresponds to 0. Using these conclusions it is definitely easier to understand the following picture:

Figure 30. Example of low level instructions of Test: vbaVarTstNe(Serial Length, 0);

If you are curious (and you should if you wanna learn RCE), probably you will be interested at the instructions stored at 0x40A3EE. There the Bad Boy MessageBox is created:

Figure 31. Some Instructions before to invoke the Bad Boy Message.

HellRaiser System Util V4 reversing

23

HELLRAISER SYSTEM UTILITY V4 REVERSING

Figure 32. Implementation and visualization of Bad Boy Message Box.

Figure 31 highlights some suspicious instructions, particularly that at the offset 0x40A3FB: MOV EAX, DWORD PTR SS:[EBP-70];
comment;

EAX = [EBP-0X70] == GLOBAL FLAG!

What does it means GLOBAL FLAG ? Imagine to use a demo program with its own limitations; usually this demo version is unlocked by means of a registration number or license key, which you must buy (or you should ) in order to unlock the target. Now the question is, how the target recognizes that you are running it as a full version? Simple for VB applications usually there is a binary variable (alias Memory location) that encodes the internal state: DEMO or FULL; this variable is our GLOBAL FLAG! So the logic scheme that represents a possible activation is: 1 Enter the Serial; 2 Global Flag = 0; 3 Test the Serials length, if passes sets Global Flag = 1; 4 First Check Routine, if passes sets Global Flag = 1; 5 Second Check Routine, if passes sets Global Flag = 1; . . If Global Flag = 1, runs program as FULL, else DEMO;

HellRaiser System Util V4 reversing

24

HELLRAISER SYSTEM UTILITY V4 REVERSING


Funny, isnt it? Our target has this logic; it wasnt so easy because VB adds a lot of indirect code to the programs. Anyway if we try to understand why the Bad Boy Message is invoked, we will discover that Stack port [EBP0x70] sets everything! Indeed, after the tests of the Serial length, our Crackme executes the following operations:

Figure 33. vbaI2Var function extracts the Integer from a Int or Long Int Variant Object.

Have you noticed the first instruction where Stack port [EBP-0x70] is initialized to -1? It means that our target starts in the REGISTERED status ! At this point a Big Main Loop appears to be clear enough: For ( int i = 1; i <= Serials Length; i++ ){... The initialization and comparison of the index i are quite evident in the figure below:

Figure 34. Start of Main Loop.

Whats happens inside this loop? First of all, our CrackMe takes the i-th UNICODE CHAR from the Serial entered through the rtcMidCharVar function. This routine has three parameters: Strings offset, Position and Length of SubString to extract. Its as well quite clear how the program takes the i-th Char, it executes the following CALL: rtcMidChar( String Offset, i, 1 );returns value is the offset of SubString of TWO bytes; Moreover, the last parameter is an Integer Variant Variable ... so, a double initialization of this object is required! Using these conclusions it becomes easier to understand the code below:

HellRaiser System Util V4 reversing

25

HELLRAISER SYSTEM UTILITY V4 REVERSING

Figure 35. The target take the i-th UNICODE Char from the Serial entered.

The SubStrings Offset of ONE UNICODE CHAR (Two Bytes) extracted before is then copied in a New String Variant Object thanks to vbaVarMove Function. At this point, the target simply converts the UNICODE CHAR in ANSI CHAR through the rtcAnsiValueBstr function and then creates a new Integer Variant Variable with this value, invoking again the vbaVarMove routine:

Figure 36. Conversion of UNICODE CHAR i-esim in to ANSI CHAR.

Now, a suspicious Routine is invoked:

Figure 37. Unknown CALL.

The piece of code above is often repeated inside fastcopy fixed.exe; as you can notice, the last call is referred to a routine at the offset 0x40392F and receives, essentially, 3 parameters: 1. 2. 3. A Integer Variant Object that contains the ANSI CHAR i-th of our Serial; A new integer Variant Object that i have called with a mysterious name: Base; Stack offset where will be stored the result of this function, it will be another Variant Object;

What is doing this routine? Well, if you read my comments in the Figure 37, you should already know the answer, but this note is the result of several mumblings and tests done. First of all, with Ollydbg I locked the stack at the offset [EBP-0xFC] to monitor the returns value of this function; therefore I observed its execution with different inputs, patching also the value of 2 parameter, alias our Base! The following table explains these results:

HellRaiser System Util V4 reversing

26

HELLRAISER SYSTEM UTILITY V4 REVERSING

st

Parameter = ANSI CHAR

nd

parameter =

BASE

Returns Value

1 = (31)16 1 = (31)16 2 = (32)16 3 = (33)16 K = (4B)16

4 3 4 6 4

UNICODE String 0301 UNICODE String 1211 UNICODE String 0302 UNICODE String 0123 UNICODE String 1023

Table 4. Inputs and outputs of the CALL fastcopy.0040392F. Returns Value is s String Variant Object stored in to the Stacks port: PTR SS:[EBP-0xFC].

Can you guess now, using the input-output table above, what this unknown CALL does? This routine simply nd converts an hexadecimal value in to a number modulo ... Base, alias the 2 parameter passed! If you guessed it correctly you are a little step inside the Reversing Zen. On the other hand if you are like me and you think that any hypothesis must be verified, you surely have stepped into this CALL to analyze its inner work. What I must say is to use my comments inside OllyDbg because I have explained every instruction of this protection scheme; in my opinion, this .TXT file ( Comments.txt ) is the REAL TUTORIAL!! After having converted the first ANSI Char in to a number modulo 4 and stored it in a new String Variant Object rd (3 parameter is moved in a New Stack Area thanks, again, vbaVarMove function), the target prepares itself to execute another loop: For (int j = 1; j <= 4; j++){... The corresponding low level piece of code is:

Figure 38. Initialization and test of Counter j, belonging to a internal loop.

As you can see in the picture above, Counter J is stored in to the Stack Port [EBP-0x1C] meanwhile ECX register is the Upper bound of our Loop and it represents the MAX NUMBER of DIGITS ( 4 ) for each number expressed in a certain Base (see the asm instruction highlighted in Green ).

HellRaiser System Util V4 reversing

27

HELLRAISER SYSTEM UTILITY V4 REVERSING


We suppose that the last jump of the Figure 38 is not verified; so our Counter J is equal to 1. In this case the program executes these actions: 1. 2. 3. Creates in to the stack 3 Integer Variant Objects initialized to 1; st Takes the Value of String Variant Object that contains the 1 Serials ANSI Char represented in Base 4; (its a Stack offset returned by vbaStrVarVal routine!) st Extracts the 1 digit of this string thanks to rtcMidCharBstr function;

Naturally, the low level instructions that execute these steps are a bit scrambled but its not so difficult understand them, as you can see in the figure below:

Figure 39. Scrambled instructions at the tests beginning of 1 digit of 1 ANSI CHAR modulo 4.

st

st

At this point, the 1 digit of the 1 char is compared with 3 ANSI CHARS: 0, 3 and 2 and the result of these tests updates an INTERNAL FLAG, located to the Stack port [EBP-0x244]. The Visual Basic function used to this scope is vbaStrCmp; it receives, as parameters, the addresses of the Strings to compare and returns a value equal to: -1 if the 1 string is less than the 2 string; st nd 0 if the 1 string is equal to the 2 string; st nd +1 if the 1 string is greater than the 2 string;
st nd

st

st

The following low level instructions explain very well how the target uses this result (stored in EAX register):

HellRaiser System Util V4 reversing

28

HELLRAISER SYSTEM UTILITY V4 REVERSING

Figure 40. Comparisons of the first digit of first Char base 4 with ANSI CHARS: 0, 3 and 2.

As you can notice in the picture above, the asm instructions used to perform these tests (marked in green) are the same ones:
st nd rd

Instructions

Case: EAX = -1

Case: EAX = 0

Case: EAX = +1

EAX 1; NEG EAX Carry Flag 1;

EAX 0; Carry Flag 0;

EAX -1; Carry Flag 1;

EAX (11CF)... SBB EAX, EAX EAX -1;

EAX (00CF)... EAX 0;

EAX (-1(-1)CF).. EAX -1;

EAX (-1+1)... INC EAX EAX 0;

EAX (0+1)... EAX +1;

EAX (-1+1)... EAX 0;

NEG EAX

EAX 0;

EAX -1;

EAX 0;

Table 5. Partial values of EAX register during the execution of Check Code; EAX is initialized with the Returns Value of vbaStrCmp function.

HellRaiser System Util V4 reversing

29

HELLRAISER SYSTEM UTILITY V4 REVERSING


So, the INTERNAL FLAG can assume only 2 values: 0 - if the 1
st

digit of the 1

st

char modulo 4 is different from 0, 2 and 3;

-1 Otherwise; Having executed all controls on the 1 digit, the target checks the flag right: if this last one is equal to 0, the nd st program simply jumps to the next control about 2 digit of 1 char else it resets the GLOBAL FLAG, causing, as we know, the appearance of Bad Boy Message:
st

Figure 41. How INTERNAL FLAG influences the value of GLOBAL FLAG!

I wanted explain in detail this type of check (first in order of appearance) because the other ones are similar, it changes only the constant digits compared. Indeed, if youll follow the normal codes flow (perhaps patching all INTERNAL FLAGS, one for each Digit of each Char converted!), you will easily understand the scheme to verify the correctness of the entire serial entered: Global Flag = -1; (for int i=1; i<= Serials length; i++){ Converts the i-th Serial char in a Number modulo Basei = (d1,d2,d3,d4)K; (for int j=1; j<= Max Digit Number; j++){ Internal Flag = (dj==(Cipher0)K) or (dj==(Cipher1)K) or ... ... or (dj==(CipherK-2)K); If (Internal Flag != 0) Global Flag = 0; } } If (Global Flag == 0) the target executes the Bad Boy Message; Else the target executes the Good Boy Message;

Notes: Serial Length == 9; Max Digit Number == 4; i define Base i equals to K;

Table 6. Protection scheme of Fastcopy fixed.exe.

HellRaiser System Util V4 reversing

30

HELLRAISER SYSTEM UTILITY V4 REVERSING


So, unrolling two loops and explaining all comparisons done, we can draft the following table:
st nd rd th

Serials Chars

1 digit

2 digit

3 digit

4 digit

(Serial[1])Base = 4

must to be different from: 0, 3, 2

must to be different from: 3, 2, 1

must to be different from: 0, 3, 1

must to be different from: 0, 2, 1

(Serial[2])Base = 3

must to be different from: 1, 0

must to be different from: 2, 0

must to be different from: 2, 1

must to be different from: 1, 0

must to be different from:

must to be different from: 8, 7, 6, 5, 4, 3, 1, 0

must to be different from: EMPTY 8, 7, 6, 5, 4, 2, 1, 0

(Serial[3])Base = 9
8, 7, 6, 5, 4, 3, 2, 0

(Serial[4])Base = 7

must to be different from: 6, 5, 4, 3, 2, 0

must to be different from: 6, 5, 4, 3, 1, 0

must to be different from: 6, 5, 4, 3, 1, 0

EMPTY

must to be equal to:

must to be equal to: EMPTY EMPTY 4

(Serial[5])Base = 13
8

must to be equal to:

must to be equal to: EMPTY EMPTY 4

(Serial[6])Base = 11
9

(Serial[7])Base = 5

must to be different from: 3, 1, 2, 0

must to be different from: 2, 3, 1, 4

must to be different from: 6, 5, 4, 3, 2, 0

EMPTY

must to be equal to:

must to be equal to: EMPTY EMPTY 8

(Serial[8])Base = 10
6

(Serial[9])Base = 6

must to be different from: 5, 4, 3, 1, 0

must to be different from: 4, 2, 3, 1, 5

must to be different from: 5, 4, 3, 2, 0

EMPTY

Table 7. Synthesis of every test inside our CrackMe.

Its now therefore simple to obtain the UNIQUE solution that solves our target. Indeed, as you can see above, the numbers belonging to a Char expressed in a certain Base , must be different exactly -1 digits; it is

HellRaiser System Util V4 reversing

31

HELLRAISER SYSTEM UTILITY V4 REVERSING


therefore clear that the only remaining digit is the right one! For example, if you consider the 2 digit of 1 char, it must to be different from numbers 3, 2, 1. This digit belongs to a Number modulo 4, we can directly assign the value 0 ... simple, isnt it?
nd st

The most careful readers have noticed that I highlighted, with orange, one cell of the last table...why? Simple, the author of this CrackMe, konstAnt, has done an error, a mathematical error: how can he test a cipher of a number modulo 5 with values 6 and 5? No ... its no good! At this point we have all the elements to calculate the correct serial:

Serial Chars

Number modulo Basei (1023)4 (2102)3 (123)9 (122)7 (84)13 (94)11 (401)5 (68)10 (201)6

Number modulo Base16 (4B)16 (41)16 (66)16 (41)16 (6C)16 (67)16 (65)16 (44)16 (49)16

ANSI CHAR

Serial[1] Serial[2] Serial[3] Serial[4] Serial[5] Serial[6] Serial[7] Serial[8] Serial[9]

K A f A l g e D I

Table 8. Secret = KAfAlgeDI!!!

HellRaiser System Util V4 reversing

32

HELLRAISER SYSTEM UTILITY V4 REVERSING


Tada! We have found the unique serial correct; indeed, when we enter this password, the congratulations of the author will appear:

Figure 42. Good Boy Message.

Well, we can finally say that we are now finished !

1.8

CONCLUSIONS

So, it was really difficult this CrackMe? In my opinion, NOT; probably the most difficult part was to unpack the file fastcopy.tmp and transform it in a working exe, without the presence of internal loader! The secrets discovered is a simple exercise of Elementary Math; sure, the choice to write everything with Visual Basic 6 was initially a challenge because I have never reversed these type of targets, but once you know which APIs are used for what and the internal structure of Variants, the analysis becomes easier. So, how many steps we have solved hellrAiser System Utility V4? Simple, only FIVE. I definitely spent more time to write this tutorial !

1.9

ERRATA CORRIGE

In the unpacking phase, I told you to have used Import Reconstructor 1.7c; indeed I used also CHimpREC by TIGA, the first 64-bit import address table rebuilder. This tool, like the first one, appends a new section when rebuilds the IAT, calling it .Tiga. So in the Figure 11, I simply confused the two tools; the Import Reconstructor renames the last section as .mackt.

HellRaiser System Util V4 reversing

33

HELLRAISER SYSTEM UTILITY V4 REVERSING

1.10 REFERENCES
To understand the loaders theory and how the packers works, I suggest you to read: i. ii. Cracking with Loaders Theory: General Approach and a Framework v1.2 by Shub Nigurrath and ThunderPwr; How to write a simple executable packer in C by Gunther;

To study how to reverse targets written in Visual Basic 5/6, I recommend to you: i. ii. Visual Basic, a decompiling approach by Andrea Geddon; VisualBasic-APIs_by_CodeRipper.zip, a zip archive of most important VB APIs posted in TutorialZ Area of ARTeam site;

1.11 GREETINGS
First of all, i want to thanks konstAnt, the author of this CrackMe, because he has introduced me to the world of Visual Basic reversing ! Then, I want to say thanks to Shub-Nigurrath and all ARTeams Member: their work is a constant stimulus for a newbie reverser like me. Naturally as well a big thanks goes to the authors of those useful tools like OllyDbg and CFF Explorer; without these last ones we will simply lose! Finally, I thank you, who have the patience to read my tutorial.

Dedicated to my mother and my father.

HellRaiser System Util V4 reversing

34

You might also like