ARTeam Tutorial

by Shub-Nigurrath

Visit: http://cracking.accessroot.com | http://forum.accessroot.com

Fishing serials from BlitzCalc and writing its Oraculum v.1.0


Information A tutorial explaining how to fish the correct serial from BlitzCalc and how to write an oraculum for this program
Target BlitzCalc 1.0.1
Available http://tripence.com/
Tools OllyDbg 1.10 (HideDebug and OllyDump plugin), Import Reconstructor 1.6, Diablo2oo2 Universal Patcher
Protection not packed
level Beginner
Category serial fishing
Author(s) Shub-Nigurrath Feb 2005
Requirements Windows XP, Firefox 1.0 and above for best viewing & printing


1. Introduction


This short tutorial is about how to write an oraculum for BlitzCalc. As usual I will fish the real serial from the program and then write an oraculum for it, using the framework I released into the Oraculum's tutorial (see http://tutorials.accessroot.com). This time I'll not include the whole sources just because you can bring them from other tutorials I released, but only the compiled program and an explanation in this pages.



2. Fishing the serial


First of all, as usual, check the main executable program (BlitzCalc.exe) using PEiD: there are no packing and any internal hashing signature so no problems patching it, but as usual we'll not change a single byte of the application indeed.

Load the file "BlitzCalc.exe" into Ollydbg. Press F9 to run it.

The program goes normally, go into the registration dialog (menu Help -> Registration Info) and then appears the registration window

 

Insert any registration Information you like and then press OK, a Bad Guy window appears telling that the serial you inserted is wrong.

Now it's time to stop the process from Olly and to see what's there under the hood.

Press ALT-K to see the call stack and you should get something like in the picture below.

We'll make as shrimps, going backwards trying to return to the source of an event. So the call-stack is an optimal way to do it.

You might notice that the bad guy message is starting to appear since the call at 41F323 then a good place where to start looking backwards is there.

 

Well, we place a breakpoint to the call at 41F373, press continue or F9 to let the application run again, re-enter the serial number we used above (or any other you like) and then we will land in the breakpoint just set.

Press F7 to enter the call at 420389 and you should land into a peice of code as the following:

Note that the call is a linear call, without jumps and other branches that directly leads to a MessageBox. The text of the MessageBox is decided by the calls between 420389 and 4203D5: if the serial you entered is correct it will display a "good boy" message, otherwise it will display the "wrong registration number" message (as shown in the picture). This is so, evidently, only a call that brings the correct message to show and display it into a MessageBox. So it's not interesting for us and, most of all, the decision if the registration number is correct or not has been done previously. Moreover if you look at the data stack (low right of Ollydng interface) you can see that the "bad registration" message is already on the stack. This definitely means that the decision has been done already.
If you place the cursor at the beginning of this call and press CTRL-R to get all the refences to this call, you will see that this call is called from several places..

So we must return to the breakpoint we placed before, at 41F373, and look the code above it. You should see something like this:

The call is a part of a switch-case construct (see beginner's tutorials from Gabri3l for a short description of what a switch is, if you're not familiar with it) which starts at 41F32E. Note that the JE at 41F32C skips the entire switch and so also the bad boy message's call at 41F373.
A way to patch the application seems to change this JE into a JMP, but the patch indeed doesn't really registers the application: it simply forces it to store the fake serial number somewhere (in the registry) and to show the MessageBox telling that the serial is correct. Indeed the application is still not registered as you might notice when you run again it.

So let search again in the code before the JE at 41F32C ..

Go to the beginning of the call where we were looking at.
The beginning is at 41F25D (remember the second blue line I placed, in the call-stack picture above?) and enter a breakpoint to see what is happening in the lines above the JE we just found.

Step the program line by line, pressing F8, and contemporarily drop an eye to the data-stack in the lowest right of the Ollydbg interface and also to the register's values, in the upper right.

Going on like this we might stop at a PUSH at the address 41F293, which pushes a "wired" serial number on the data stack.

If you follow a little the code after this PUSH you might see that this serial number is a banned one, against which the software is checking. To easily check what I'm telling you enter this serial as your serial in the program interface, soon the program will complain that the serial you are trying to use has been black-listed.

Go still forward step-by-step with F8 and you soon should land in the place below:

As written in the picture, the place where another serial appears from underlying calls is the MOV instruction at 41F2F4. Interestingly for us the serial appears into one of the registry, the ECX register.

PS You might see this instruction as MOV ECX,DWORD PTR SS:[EBP-18], depending on your Ollydbg settings. Why this difference? Well, it's not a long story but falls a little outside this tutorial target. Anyway briefly, the memory addresses under the EBP value (EBP - something) in the data stack, are considered local variables for the current function, while the memory addresses above the EBP (EBP + something) are considered global variables, which are visible even from outside the current function. The reason why this happens implies to explain how the data stack grows and so on.. so let it to be fully explained for another tutorial ^__^

Anyway we are at the end of the fishing process, because we have now this situation:

the registers have some interesting values: our fake serial and the real serial the program calculated. Try to insert it in the registration dialog box and you should get the program fully registered.

 

Name: ARTeam
Serial: 51-9a1d-eaf4-e51f-aa
 

Ok, note that if you now have a registered program you will not be able to go on with the following part of this tutorial.

To erase the registration information go into the window registry and delete these two keys:

\HKEY_CURRENT_USER\Software\Tripence Software\BlitzCalc\UserInfo\Name

\HKEY_CURRENT_USER\Software\Tripence Software\BlitzCalc\UserInfo\RegCode



3. Writing the Oraculum

I'll not explain again which are the advantages of writing an oraculum for a program, but directly jump to the code of the callbacks for this specific program. I'll assume as well you have already read and understood the tutorial "Guide on How to play with processes memory, write loaders and Oraculums" by myself, available in the tutorials section of ARTeam.

Following the instructions of that tutorial the things left to say are very few, because in this case the program is very simple.

There are two main steps you should do:

Step 1: take the standard project described into that tutorial and write new Callbacks as following:

void DoPatch_callback(COraculum *oraculum, DWORD dwMemoryPatchAddr) {

    oraculum->WriteProcessMemory(oraculum->GetPI()->hProcess,
              (LPVOID)dwMemoryPatchAddr,
    (void*)&COraculum::HALT_CODE, HALT_SIZE, NULL);
// places the EBFE loop

}

void DoActionPatch_callbackStop(COraculum *oraculum) {

   
//ECX contains the pointer to real code!
    oraculum->ReadProcessMemory(oraculum->GetPI()->hProcess,
              (LPVOID)oraculum->GetProcessContext()->Ecx,
    oraculum->GetProcessBuffer(),100,NULL);
}

void DoActionPatch_callbackResume(COraculum *oraculum) {

    //Writes the message, format it correctly to handle UNICODE
    char str[256];
    char tmpStrOut[256];
    unsigned char ch1=0, ch2=0;
    int idx1=0, idx2=0;
    do {
        ch1=*(oraculum->GetProcessBuffer()+idx1);
        ch2=*(oraculum->GetProcessBuffer()+idx1+1);
        tmpStrOut[idx2]=ch1;
        idx1+=2;
        idx2++;
    } while (ch1!=0 || ch2!=0);

    sprintf(str,"Shub-Nigurrath says that your correct serial is %s", tmpStrOut);

    oraculum->pushMessage(str);

}


Note that the real serial number is stored into an UNICODE string so there's a complication indeed because even if the COraculum class correctly handle UNICODE or ASCII strings, the printing of the result must be done properly.
Consider that an UNICODE representation of normal ASCII characters is made by the normal ASCII code followed by a 00: 'a' becomes 6100 which is the ASCII code of 'a' 61 with a trailing 00. Thus our serial is represented as following in memory:

01391FE8 35 00 31 00 2D 00 39 00 61 00 31 00 64 00 2D 00  5.1.-.9.a.1.d.-.
01391FF8 65 00 61 00 66 00 34 00 2D 00 65 00 35 00 31 00  e.a.f.4.-.e.5.1.
01392008 66 00 2D 00 61 00 61 00 00 00 08 00 00           f.-.a.a...


the normal chars alternates with 00 values and the string terminates with a double 00. The DoActionPatch_callbackResume implements a simple not optimized do{}while loop which takes only the ASCII chars and places them into a new buffer.

 

Step 2: insert the pattern to be searched in the victim's image. A proper pattern is a piece of code which have only local references, to lines of code not too far (not CALLs, not far JMPs). Why? Simple, when a new release comes out, the offsets and call address will surely change then also the exadecimal representations of the asm code. A pattern relative to such calls or jmps will probably not survive to a new release.

For this program one right pattern is exactly where we stopped and found the correct serial, because it's a block of instructions without external references: Wel, to be precise, one there is, is the stack position of the local variable LOCAL.6, which if the above code in future releases will change, might change..but for this tutorial we'll ignore it.

0041F2F4 |. 8B4D E8 MOV ECX,[LOCAL.6] ; here the serial appears into the ECX register
0041F2F7 |. 83C4 20 ADD ESP,20
0041F2FA |. F6D8    NEG AL
0041F2FC |. 1BC0    SBB EAX,EAX
0041F2FE |. 40      INC EAX
0041F2FF |. 83C1 F0 ADD ECX,-10
0041F302 |. 8BF0    MOV ESI,EAX

which is in bytes: 8B4DE883C420F6D81BC04083C1F08BF0

which becomes this pattern :x8B:x4D:xE8:x83:xC4:x20:xF6:xD8:x1B:xC0:x40:x83:xC1:xF0:x8B:xF0
The code we want to stop at is at address 0041F2F4, so at an offset of 0x0 forward.

This is then the final line you should add at the beginning of the main() part of the oraculum

Oraculum.AddPattern("
:x8B:x4D:xE8:x83:xC4:x20:xF6:xD8:x1B:xC0:x40:x83:xC1:xF0:x8B:xF0", 0x0);

If your addresses are different, it's not a problem indeed, because the Oraculum class worries of all the magic using a search routine which searches the string inside the program and moves to 0x0D offset from it. Thus the oraculum will work also for relocated processes.

Compile everything and run the program as "BlitzCalc_oraculum blitzcalc.exe". It launches the main program and stay underground waiting you to go into the registration dialog, enter any serial you like for any name and press OK. Then the oraculum terminates the victim's process and reports to you what you needed.

C:\Program Files\BlitzCalc> BlitzCalc_Oraculum.exe BlitzCalc.exe
Messages Stack dump, read information in reverse order..
--------------------------------------------------------
3> The target process has been terminated! Restart it directly and enter the gathered information..
2> Shub-Nigurrath says that your correct serial is 51-9a1d-eaf4-e51f-aa
1> Location to patch: 1F2F4(offset), 41F2F4 (memory)

 

NOTE: if the Oraculum seems to fail telling that it cannot get the context of the program it much probably means that there's an already running instances of BlitzCalc into the tray area. Close it, because the program do a check on multiple instances and if there's one already running closes the new one immediately.

As you might have noticed the memory address that have been patched iis the same we found in previous section.

I attached to this tutorial only the main program of the whole sources, so as to have something complete to read, you might be able to re-create the whole program (I did it to save space).
 



4. Conclusions

Lesson Learnt

This time we explored a little deeper again how to fish serials and how to transform the information we obtained into an oraculum.

have phun!


 
5. Greetingz

[MAIN TEAM]
| Nilrem | Enforcer | Ferrari | Pompeyfan(ex-member) | MaDMAn_H3rCuL3s | EJ12N | Kruger |
Shub-Nigurrath | Jdog45 | R@adier | Teerayoot | ThunderPwr | Eggi | Bone Enterprise | Gabri3l | KaGra

*****************************

Exetools | Woodmann | VCT | TSRh | Sir JMI | | FEUERRADER | Britedream | cl0ud (Mephisto) | Zest | Hobgoblin | Nullz | hosiminh | Everyone I missed & you


(.|.)
 ).( (¯`·._.·[¯¨´*·~-.¸¸,.-~*´¨&8~) Ŝħůβ¬Ňïĝµŕřāŧħ ¨´*·~-.¸¸,.-~*´¨]·._.·´¯)
( v )
 \|/