HellrAiser System Utility V4 Reversing
description
Transcript of HellrAiser System Utility V4 Reversing
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: I’ve never reversed this type of target: Because is it so hard? Will I be able to solve it?
Probably both..
2) Challenge: isn’t it a real challenge to try discovering some weakness behind a protection scheme?
3) Increasing my knowledge: my Basket’s 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 you’ll 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 Table of Contents ................................................................................................................................. 1
1.2 Tools used ............................................................................................................................................ 2
1.3 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 Fourth Step: Study of Visual Basic targets reversing ........................................................................... 17
1.7 Fifth step: Find the secret inside fastcopy fixed.exe ........................................................................... 17
‘HELLRAISER SYSTEM UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 2
1.8 Conclusions ........................................................................................................................................ 33
1.9 Errata Corrige ..................................................................................................................................... 33
1.10 References ......................................................................................................................................... 34
1.11 Greetings ............................................................................................................................................ 34
1.2 TOOLS USED
A ring 3 debugger: it’s a real challenge to discover a working alternative to OllyDbg , it’s the most
famous and probably powerful ring 3 debugger available on Microsoft Operative Systems; it’s free
and extensible with many plugins. Personally, in my Ollydbg copy, I installed these ones:
o Scherzo’s 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: don’t misunderstand me, i don’t 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 it’s 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: it’s really needed for this kind of passions !
‘HELLRAISER SYSTEM UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 3
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 there’s someone here who doesn’t 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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 4
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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 5
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 it’s 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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 6
1. In the Processes’ view, as a son of the process Procexp.exe, you can find the process
‘hellrAiser.Fms4.exe ‘ (Child process);
2. If you continue looking at the processes list, after a little delay, a second Process appears in the root
level of Process’s Tree (no Parent Process), which is called ‘fastcopy.tmp’;
3. 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 loader’s 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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 7
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 it’s important unpack again the target
to have a clear vision of all things so far. So:
1. fire up OllyDbg;
2. go down to the last jump instruction before a zero padded area;
3. put here a Hardware Breakpoint and press Run;
4. whenever the program stops, remove the breakpoint and execute the jump instruction (F7);
5. 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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 8
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
are underlined in green in the 5th
snapshot inside Figure 8 ) but the Entry Point’s 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 2nd
important thing to do ( the 1st
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. Attach the Active Process ‘hellrAiser.fms.exe’; in reality, this target is in suspend state under OllyDbg
at the address 0x4018A0;
2. In the Area ‘Imported Functions Found’ press Mouse’s Right Button -> Advanced Commands ->
Select Code Section(s) -> a new dialog will appear in front of you and push ‘Full Dump’ button;
3. name the new file ( i.e hellrAiser.fms_.exe );
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 don’t 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. In the OEP edit control, enter: 0x18A0; ( Relative Virtual Address = Virtual Address – Image Base
Address -> 0x18A0 = 0x4018A0 – 0x400000 )
5. 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 Mouse’s right button and select: ‘ Follow in Dump ’ -> ‘ Memory Address ’ we land
in this memory area:
‘HELLRAISER SYSTEM UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 9
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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 10
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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 11
So, why don’t change the .tmp extension in .exe ?
Figure 13. Result of file’s 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 system’s 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 don’t 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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 12
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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 13
Figure 17. fastcopy.exe is an malformed UPX target!
From the figure above, it’s 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
fastcopy.exe. We will anyway just use the 1st
Olly meanwhile the 2nd
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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 14
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, // handle to process whose memory is written to
LPVOID lpBaseAddress, // address to start writing to
LPVOID lpBuffer, // pointer to buffer to write data to
DWORD nSize, // number of bytes to write
LPDWORD lpNumberOfBytesWritten // actual number of bytes written
);
So we set a breakpoint for each call to WriteProcessMemory and therefore press F9 inside Ollydbg. The result
is that Olly land us here:
‘HELLRAISER SYSTEM UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 15
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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 16
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 doesn’t anymore need its loader. We can
finally throw away the loader hellrAiser.fms.exe and reverse the new fastcopy fixed.exe!
‘HELLRAISER SYSTEM UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 17
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 don’t 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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 18
2. what this function does; the SDK could help!
3. 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 2nd
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
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 1st
field, marked in orange, describes the type of the Variant variable; in the following table I highlighted
the most used type values:
Type Name Internal Type Name Hex Value
Empty VT_EMPTY 0
Null VT_NULL 1
Error / Missing VT_ERROR 0x0A
Boolean VT_BOOL 0x0B
Int VT_I2 2
Long Int VT_I4 3
Single Real VT_R4 4
Double Real VT_R8 5
String VT_BSTR 8
Array VT_ARRAY 0x2000
Reserved VT_RESERVED 0x8000
‘HELLRAISER SYSTEM UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 19
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 -- -- -- -- -- -- Array’s 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 Win32’s MesageBox. If
you have read the documents posted by CodeRipper in ARTeam Forums, you shouldn’t find it difficult (it’s
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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 20
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 it’s 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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 21
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,...)
It’s interesting to underline, using following figure, that this function indeed doesn’t free stack’s 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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 22
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 return’s 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 Stack’s ports reserved for the parameters of rtcInputBox function (in
other words it executes the CALL vbaFreeVarList( 7, 1st
param, 2nd
param, ... )) and therefore starts a
classic check on Serial’s 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 Serial’s Length, compare Variant Variables; for this reason the
Serial’s 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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 23
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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 24
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]; EAX = [EBP-0X70] == GLOBAL FLAG! comment;
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 Serial’s 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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 25
Funny, isn’t it? Our target has this logic; it wasn’t 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 [EBP–0x70] 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 <= Serial’s Length; i++ ){...
The initialization and comparison of the index i are quite evident in the figure below:
Figure 34. Start of Main Loop.
What’s 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: String’s offset, Position
and Length of SubString to extract. It’s as well quite clear how the program takes the i-th Char, it executes the
following CALL:
rtcMidChar( String Offset, i, 1 );return’s 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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 26
Figure 35. The target take the i-th UNICODE Char from the Serial entered.
The SubString’s 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. A Integer Variant Object that contains the ANSI CHAR i-th of our Serial;
2. A new integer Variant Object that i have called with a mysterious name: Base;
3. 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 return’s 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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 27
1st Parameter = ANSI CHAR 2
nd parameter = BASE Return’s Value
“1” = (31)16 4 UNICODE String “0301”
“1” = (31)16 3 UNICODE String “1211”
“2” = (32)16 4 UNICODE String “0302”
“3” = (33)16 6 UNICODE String “0123”
“K” = (4B)16 4 UNICODE String “1023”
Table 4. Inputs and outputs of the CALL fastcopy.0040392F. Return’s Value is s String Variant Object stored in to the
Stack’s port: PTR SS:[EBP-0xFC].
Can you guess now, using the input-output table above, what this unknown CALL does? This routine simply
converts an hexadecimal value in to a number modulo ... Base, alias the 2nd
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
(3rd
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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 28
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. Creates in to the stack 3 Integer Variant Objects initialized to 1;
2. Takes the Value of String Variant Object that contains the 1st
Serial’s ANSI Char represented in Base
4; (it’s a Stack offset returned by vbaStrVarVal routine!)
3. Extracts the 1st
digit of this string thanks to rtcMidCharBstr function;
Naturally, the low level instructions that execute these steps are a bit scrambled but it’s not so difficult
understand them, as you can see in the figure below:
Figure 39. Scrambled instructions at the test’s beginning of 1st
digit of 1st
ANSI CHAR modulo 4.
At this point, the 1st
digit of the 1st
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 1st
string is less than the 2nd
string;
0 if the 1st
string is equal to the 2nd
string;
+1 if the 1st
string is greater than the 2nd
string;
The following low level instructions explain very well how the target uses this result (stored in EAX register):
‘HELLRAISER SYSTEM UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 29
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:
Instructions 1st Case: EAX = -1 2
nd Case: EAX = 0 3
rd Case: EAX = +1
NEG EAX EAX ← 1;
Carry Flag ← 1;
EAX ← 0;
Carry Flag ← 0;
EAX ← -1;
Carry Flag ← 1;
SBB EAX, EAX EAX ← (1–1–CF)...
EAX ← -1;
EAX ← (0–0–CF)...
EAX ← 0;
EAX ← (-1–(-1)–CF)..
EAX ← -1;
INC EAX EAX ← (-1+1)...
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 Return’s Value of
vbaStrCmp function.
‘HELLRAISER SYSTEM UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 30
So, the INTERNAL FLAG can assume only 2 values:
0 - if the 1st digit of the 1
st char modulo 4 is different from “0”, “2” and “3”;
-1 – Otherwise;
Having executed all controls on the 1st
digit, the target checks the flag right: if this last one is equal to 0, the
program simply jumps to the next control about 2nd
digit of 1st
char else it resets the GLOBAL FLAG, causing,
as we know, the appearance of “Bad Boy” Message:
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 you’ll follow the normal code’s 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<= Serial’s 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 Basei equals to K;
Table 6. Protection scheme of Fastcopy fixed.exe.
‘HELLRAISER SYSTEM UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 31
So, unrolling two loops and explaining all comparisons done, we can draft the following table:
Serial’s Chars 1st
digit 2nd
digit 3rd
digit 4th
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
(Serial[3])Base = 9
must to be different
from:
8, 7, 6, 5, 4, 3,
2, 0
must to be different
from:
8, 7, 6, 5, 4, 3,
1, 0
must to be different
from:
8, 7, 6, 5, 4, 2,
1, 0
EMPTY
(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
(Serial[5])Base = 13 must to be equal to:
8
must to be equal to:
4
EMPTY EMPTY
(Serial[6])Base = 11 must to be equal to:
9
must to be equal to:
4
EMPTY EMPTY
(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
(Serial[8])Base = 10 must to be equal to:
6
must to be equal to:
8
EMPTY EMPTY
(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.
It’s 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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 32
therefore clear that the only remaining digit is the right one! For example, if you consider the 2nd
digit of 1st
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, isn’t it?
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 ... it’s no good!
At this point we have all the elements to calculate the correct serial:
Serial Chars Number modulo Basei Number modulo Base16 ANSI CHAR
Serial[1] (1023)4 (4B)16 “K”
Serial[2] (2102)3 (41)16 “A”
Serial[3] (123)9 (66)16 “f”
Serial[4] (122)7 (41)16 “A”
Serial[5] (84)13 (6C)16 “l”
Serial[6] (94)11 (67)16 “g”
Serial[7] (401)5 (65)16 “e”
Serial[8] (68)10 (44)16 “D”
Serial[9] (201)6 (49)16 “I”
Table 8. Secret = “KAfAlgeDI”!!!
‘HELLRAISER SYSTEM UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 33
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 UTILITY V4’ REVERSING
‘HellRaiser System Util V4’ reversing 34
1.10 REFERENCES
To understand the loaders theory and how the packers works, I suggest you to read:
i. “Cracking with Loaders Theory: General Approach and a Framework v1.2” by Shub Nigurrath and
ThunderPwr;
ii. “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. “Visual Basic, a decompiling approach” by Andrea Geddon;
ii. “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 ARTeam’s 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.