Mostrar mensagens com a etiqueta Cracking. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta Cracking. Mostrar todas as mensagens

terça-feira, 18 de outubro de 2011

A crack in Redgate's Reflector


Above all things related to software development, those who get my warmest affection are the protection mechanisms. Almost every application out there (mainly commercial ones) have a different approach that materializes the individual vision of one programmer. Some choose commercial protection oriented software, some choose cryptography, some encode, other use math, etc. What makes them different is what makes me interested in them. This interest took me yesterday to Redgate's Reflector. But before continuing let me state the following: although I don't favor cracking, especially when a program has prices affordable by everyone like Reflector does, I believe that cracking is a necessity. Be it for validating the strength of the protections in place, be it for bypassing those protections and validate that a piece of software we just bought or downloaded it from the Internet does what it acclaims.
With that said let me tell you why I'm posting about a bypass of Redgate's Reflector protection scheme: because it just took me less than one minute to find it. Considering all the obfuscation effort that Redgate put on Reflector, this seems like they cracked open their own safety mechanisms.  Given their great work with Reflector, I think that such an error deserves a public post.

The story begins when I needed to use Reflector and it informed me that I had to buy the full version if I wanted to continue using it.


If you have been following the news, my country -Portugal- is in a huge recession, which means that we don't have money. So, as I only use Reflector a couple of times  a year, I decided to see if I could do anything to convince Reflector to work just one more time. I grabbed my second favorite debugger, Windbg, and run Reflector. As the application initialized, it started dumping some data to the debugger's output window:
 
Reflector.exe Information: 0 : Retrieving licence for .NET Reflector 7.0 {2447b2f0-fe09-4d98-8e51-93b07466303e}
Reflector.exe Information: 0 : Machine hash is local
Reflector.exe Information: 0 : Local machine hash is XXXX
Reflector.exe Information: 0 : Persisting
Reflector.exe Information: 0 : Product .NET Reflector
Reflector.exe Information: 0 : Activated False
Reflector.exe Information: 0 : Edition
Reflector.exe Information: 0 : Serial Number
Reflector.exe Information: 0 : Blob {2447b2f0-fe09-4d98-8e51-93b07466303e}
Reflector.exe Information: 0 : Hash XXXX
Reflector.exe Information: 0 : Trial Tampered
Reflector.exe Information: 0 : Expires 2011-11-13 02:59:43 UTC
Reflector.exe Information: 0 : Extended False
Reflector.exe Information: 0 : Installed 2011-10-14 02:59:43 UTC
Reflector.exe Information: 0 : First Used 2011-10-14 02:59:43 UTC
Reflector.exe Information: 0 : Last Used 2011-10-17 09:52:05 UTC
Reflector.exe Information: 0 : Stored to registry

I thought the value {2447b2f0-fe09-4d98-8e51-93b07466303e} was a curious one as it resembled a GUID. Also, the phrase "Stored to registry" seemed, hmmm... suspicious? I grabbed that value and searched the registry for it. This value was being used here:


I deleted the key from the registry and rerun Redgate's Reflector, and guess what?  The trial date was reset.

Ups!...

PS: After I found this, I searched the Internet for this trial reset hack and found that it is known for some time. But, I didn't find any reference to this leak of information by Redgate. This is the second reason why I decided to post it.

sábado, 6 de agosto de 2011

QT 4 You

I was asked a couple months ago by a friend of mine to “tweak” a software protection as he wanted to “evaluate” more “thoroughly” the targeted program. As I went in to it, I found the protection scheme very interesting as it involved a couple of cross platforms based engines interacting together to serve as anti-hacking security licensing system. One was Qt, the other being JavaScript. It was the second time that I came against a Qt based software. The first time thought, I just used the basic cracking skills every reverser uses with Windows GDI apps. But this time I needed to go deeper to understand the cross VM interactions, and a bigger understanding of the Qt framework was needed, so, I engaged into searching for more info on the subject. The results were quite poor, except for an article by Daniel Pistelli, who now works at Hex Rays (coincidence that IDA has been reassembled using this framework?).

Besides his article, not much on the subject of reversing Qt code seemed to be around. Since then I was faced with a fair amount of Qt applications, even Portuguese ones, so I decided to post my thoughts on the subject, and build a tutorial for the 4th version of Qt (coincidentally its also the same version of IDA 6.1, hihi):

Note: The Qt platform has an OO approach, so consider before reading this tutorial, to gather some insight about reversing C++ stuff, like RTTI, MS calling convention, virtual functions, etc.

For the purpose of this demonstration I used a demo application who accompanies the Qt SDk called sdi.exe, located in the examples/mainwindows/sdi folder. You can use any program you wish, to follow this explanation, thought.

1. Recognizing the Entrypoint

Usually looks like this and Olly is smart enough to identify it as it is the EP defined in the PE header.

2. How to find Main?

Consider Main function source code. Let’s see what do we need to find it’s corresponding assembly code, and what this code looks like after compilation.

2.1. First step is to search for all inter-modular calls and locate the imported dispatcher function qWinMain defined in QtCore4.dll.

2.2 Second step, select QtCore4.qWinMain and jump into it’s code definition.

2.3. The first call after QtCore4.qWinMain sets up memory. But, we are impatient and we want QMain. QMain function will always be the second call, as highlighted in the figure.

To verify if we’ve selected the correct function call, go up some lines and the following api calls should be present:

- GetCommandLineW

- QString::fromWCharArray

- QString::toLocal8Bit

- QByteArray::detach

2.4. And we’re in QMain

2.5. The startup address is usually pointing to the start of the .CODE section

That is 401000 in this case.

3. Code analysis
3.1.
Instruction 1 – Initialize resources

If we enter the function, we should see the resources being pushed and the qRegisterResourceData function being called:

3.2 Instruction 2 – Instantiate QApplication

Pretty easy to follow right? The QApplication class is calling it’s constructor with the following arguments: Arg1 = argc, Arg2 = argv, Arg3 = compile_version

3.3.
Instruction 3


3.4. Instruction 4
3.5. Instruction 5

This function calls all the subclasses constructors

3.6. Instruction 6
3.7. Instruction 7
4. Intercept Messages in Qt

Messages in Qt are set thru slots definition. Slots are then connected using the connect macro to a QWidget based class. As sampled in the code:

So we have here 3 types of message redirection, the first one “saveAsAct” is defined in the slot set of the MainWindow class. “saveAsAct” will be made part of the MainWindow class dispatcher table.

The second one, “closeAct”, is defined as an overload of QMainWindow superclass, so it will not be part of MainWindow class dispatcher table, but will be dispatched thru MainWindow dispatcher function. But as “closeAct” is not found in MainWindow class dispatcher table it will be forwarded to QMainWindow superclass dispatcher using an Event class. The definition of “closeAct” is:

Finally “exitAct” is applied or connected to qApp. qApp is an instance of QApplication, so it can’t be intercepted in the MainWindow dispatcher function, but in QApplication dispatcher function.

Considering that everything was easy till now, this will be the “hard” part of the process, getting to trace the GDI interaction. Let’s see how we can accomplish this task. Basically there are three approaches that can be used:

4.1. Find and set a conditional breakpoint at QMetaObject::metacall with [esp+4] == object addr

The object is any GDI particular object like a QTextControl, QMainWindow, etc. that you might know it’s memory address.

4.2. Set a conditional breakpoint on Q<class of object>::qt_metacall with [esp+8] == WM_

4.3. Set a breakpoint on QMainWindow::qt_metacall (QMainWindow is defined in QtGui4.dll). This being a special case of the previous one.

On stop set a breakpoint on .code section of main executable, it should stop on the Qt dispatcher.

In the main Qt dispatcher built by the compiler, Olly tells us that there are 6 cases on switch.

The six destinations are set here:

Which correspond to the slots definitions of MainWindow class:

4.4. To target messages attached to events, set a breakpoint on QMainWindow::qt_metacall, on stop set a breakpoint on QMainWindow::event. After break set a new breakpoint in the .code section of main executable, it should stop on the Qt function you’re after.

For example, tracing the MainWindow::Close, after following the steps defined before we reach:


Just to confirm we’re in the right place let’s enter the first call:

Which is maybeSave() function who’s definition is:

See the corresponding text? We’re in the right place.

For the sake of completeness, there’s a caveat you need to be aware regarding the first approach I presented: Setting a breakpoint in QMetaObject::metacall. After entering QMetaObject::metacall and setting a breakpoint on the user section code of the main module, it won’t enter immediately in the function code we’re after; instead the metacall will just try to find the virtual stub function responsible for the dispatching. For resolving this, all you need is let the code enter in the Qt core dispatcher and then set a second section code breakpoint in the main module and finally you’ll be there.

Ufff… Good luck in you reversing.

Hope you enjoyed it!


PS: If you want the printed version of this text you can get it here.

sábado, 2 de julho de 2011

Cracking a Pimp

Just came back from vacations and found the Pimp My Crackme contest. Although I'm not in time to participate in the competition, being a follower of the first prize authors work, I decided to take a look at their challenge.
What I found was a really interesting and defying piece of protection software, and I think worth mentioning in a post about cracking and RE.
What I'll be referring here though, will be just a specific piece of code that blocks the reverser from tracing from withing some debuggers, Olly being one of the affected, and not the entire puzzle cracking. If you're using Windbg you won't have to deal with this.

This specific issue relates to the authors having used a known issue where some debuggers get lost or fail to synchronize when an LDT is used to detour the execution path.

The reversed source code to setup the LDT entry is this:
codeSegment = getCodeSegment(); // CS=0x1B
GetThreadSelectorEntry(GetCurrentThread(),
                    codeSegment,
                    &SelectorEntry);
SelectorEntry.LimitLow = 0xFFEF;
SelectorEntry.HighWord.Bytes.Flags2.LimitHi = 0x7;
pHandle = GetCurrentProcess();
error = setLDT(pHandle,
            (int *)0x7FF,
             &SelectorEntry); // LDT = 0x7F8
...
memcpy(farCallClone, farCall, 0x1Fu);
In process, we've got this selector before setup:
And this afterwords:
Flags2 in LDT_ENTRY comprises LimitHi, Sys, Reserved_0, Default_Big, and Granularity in the selector entry. Being its definition:
DWORD LimitHi :4;
DWORD Sys :1;
DWORD Reserved_0 :1;
DWORD Default_Big :1;
DWORD Granularity  :1;
So they're setting up limitHi = 0x7 for selector entry 0x7FF. What this means to Olly, is that it fails to trace when far jumping, and consequently we fail to use it to find the correct key. To bypass this "protection" we need to fix the jumped segments to be the same than our start up segment. There are a couple of ways to do this, the simplest one I found for this case is just to patch position:
009200DD call far 07FF:00000000
to our original execution segment:
009200DD call far 001B:00000000
Now, the funny part is that they have escalated the problem using multiple segments. I'm not going to delve much in the cracking process or explain how the protection works, but in order to explain how the various segments are utilized, I need to refer that the core of the protection lies in a virtual machine architecture. This virtual machine has a set of functions that virtualize it's domain operations. Aside from other interesting approaches used, this functions where laid out, each one on it's own LDT segment. And shuffled after key validation. So you can imagine how Olly must feel, always jumping around segments.
How can we bypass this? As I pointed out before, we need to maintain execution to our home segment 0x1b. How can we do this? patching the key function that distributes all the work of the VM: I called it CallVMInstruction.
Replace this function with this code:
0040CD95 mov word ptr ss:[ebp-2],1B
0040CD9B jmp short pimp_cra.0040CDC1
0040CD9D nop
0040CD9E nop
0040CD9F nop
0040CDA0 push ebp
0040CDA1 mov ebp,esp
0040CDA3 sub esp,14
0040CDA6 mov eax,[arg.1]
0040CDA9 and al,0F8 
0040CDAB shr eax,1
0040CDAD mov edi,eax
0040CDAF shl eax,2
0040CDB2 add eax,edi 
0040CDB4 lea eax,dword ptr ds:[eax+91FE14] 
0040CDBA mov eax,dword ptr ds:[eax] 
0040CDBC mov dword ptr ss:[ebp-6],eax 
0040CDBF jmp short pimp_cra.0040CD95
0040CDC1 mov edi,dword ptr ds:[AF8EF8]
0040CDC7 push [arg.2]
0040CDCA call far fword ptr ss:[ebp-6]
What this code does is it resolves dynamically the function address to our home segment, based on the segment index passed as an argument to the dispatcher and retained in a VM call dispatcher table.

With this you can set a breakpoint at address 0x0040CDCA. Now just relax and wait for the key validation, and you can now trace all the virtual machine operations.

Finally two simple last patches in order to prepare for the flush and hashing operations:
Replace the code at address:
00403046 mov eax,9200C0
0040304B nop
0040304C nop
0040304D nop
0040304E nop
0040304F nop
00403050 nop

00403243 mov eax,9200C0
00403248 nop
If you find any others function that need to be patched, now you know what to do. Consider it an exercise.

Just a side note about a second problem that I found while debugging the crackme. The authors used a far call stub function for the previously discussed purpose. They rebased this function to address zero. Ollydbg gets totally lost when trying to trace a zero base address. The way I found to successfully trace the stub calls was to instead of setting a breakpoint in address zero, I set the breakpoint in the second instruction, address 4, at lea eax,dword ptr ds:[eax*4+8] instruction.
The reversed code for it is again presented here:
...

BaseAddress = 4;
RegionSize = 4092;
pHandle = GetCurrentProcess();
error = NtAllocateVirtualMemory(pHandle,
              &BaseAddress,
              0,
              &RegionSize,
              MEM_TOP_DOWNMEM_RESERVEMEM_COMMIT,
              PAGE_EXECUTE_READWRITE);
if ( error >= 0 )
{
 farCallClone = 0;
 memcpy(farCallClone,
        farCall,
        0x1F);
....

Good look finding the correct key.