Professional Documents
Culture Documents
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
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 !
1.3
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):
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.
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:
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
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:
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:
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.
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;
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;
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:
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:
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.
10
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:
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!
11
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):
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.
12
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:
13
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
14
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:
15
RECORD FIELDS
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:
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!
16
1.6
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
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!
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
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 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
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
18
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
--
--
--
--
--
--
--
--
--
--
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.
19
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:
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.
20
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:
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:
21
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:
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
22
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.
23
Figure 31 highlights some suspicious instructions, particularly that at the offset 0x40A3FB: MOV EAX, DWORD PTR SS:[EBP-70];
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 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;
24
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:
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:
25
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:
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:
26
st
nd
parameter =
BASE
Returns Value
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:
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 ).
27
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):
28
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
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.
29
digit of the 1
st
-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;
30
Serials Chars
1 digit
2 digit
3 digit
4 digit
(Serial[1])Base = 4
(Serial[2])Base = 3
(Serial[3])Base = 9
8, 7, 6, 5, 4, 3, 2, 0
(Serial[4])Base = 7
EMPTY
(Serial[5])Base = 13
8
(Serial[6])Base = 11
9
(Serial[7])Base = 5
EMPTY
(Serial[8])Base = 10
6
(Serial[9])Base = 6
EMPTY
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
31
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
K A f A l g e D I
32
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.
33
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.
34