December 2006


Lately many programs are using Virtual Machine code inside, it’s not so hard to deal with VM and it depends on the complexity of the VM. Fundamentally once you have understand the VM structure and some opcodes you are almost done because it’s a matter of time. This time the problems arise when you have to change one or more bytes because the entire VM instructions are surrounded by a nasty anti-patch check. I don’t describe the VM used in the crackme but I’ll focus my attention over the instruction I want to patch, the good/bad boy conditional jump:

Orp_VM_1Click to enlarge

The idea is to patch the conditional jump at 415638 letting it to accept any serial, the new instruction would be:
75 00 jnz 0040563A
If you try to patch the instruction the crackme won’t run anymore because an exception will occour. As I said before there are some anti-patch checks; the crackme uses the VM instructions in his anti-patch cheching routine and you can’t patch the VM’s instructions. So, what can I do? The first thing to do is to start looking at the code which lead me to the snippet above:

Orp_VM_2Click to enlarge

This is the last part of the VM instruction that preceed the check I showed you above. Obviously the snippet above is called many times (because an instruction is called many times…) and each time the loop (40D8E2/40D8ED) extracts the offset of the next instruction. The next instruction address is obtained adding the offset to the base address (which is 40CF60). Well, seems to be unpatchable or atleast very hard to patch but there’s a little flow in it.

Maybe you can’t patch a byte of a generic VM instruction but you can surely patch something else, I’m talking about the dwords from 41555F to 41557B. Firstly these bytes are not inside a VM instruction, they won’t be executed; secondly they are not used in the code, I mean they are not used in the various anti-patch routines. So, I can change them a little. I don’t need to change all the bytes, one dword is enough.

The idea is to create a new VM instruction, almost similar to the one I wanted to patch. The new instruction will have:
75 00 jnz 0041563A
instead of:
75 01 jnz 41563B
In this way I always pass through the good boy. I’ll add the new instruction’s bytes starting from address 409704. Now, let’s see how can I do such a change. First of all, it’s better to look at the last iteraction of the loop:

xor edx, [ebx+28h] <– 24CA1F46 ^ [41555F] = 24CA1F46 ^ 24CA4311 = 5C57
add edx, [ebx+14h] <– 5C57 + 40CF60 = 412BB7
xor eax, [edx] <—— D8EEEC32 ^ [412BB7] = D8EEEC32 ^ D8EE6AB9 = 868B
add eax, [ebx+14h] <– 868b + 40CF60 = 4155EB

Ok, this is the normal situation. As I said before the new instruction is at 409704 so if I want to find the new value of [41555F] I have to go backward:

409704 – 40CF60 = FFFFC7A4
FFFFC7A4 ^ D8EEEC32 = 27112B96 <— I’ll put 0x27112B96 at [409700]. It’s the new [412BB7]
409700 – 40CF60 = FFFFC7A0
FFFFC7A0 ^ 24CA1F46 = DB35D8E6 <– I’ll put 0xDB35D8E6 at [41555F]

Crackme solved!

Click here to download the original and the patched version of the crackme.

Here’s the new version of his crackme. No encryption this time, the Virtual Machine code and data are visible. It’s harder than the previous version and seems like it’s unpatchable… The file is available at Woodmann’s rce forums

Good Luck!

Here is a nice crackme written by Orp. At first I did take only a little glance at the crackme but I decided to give it a try after reading this comment made by Orp “im not using code obfuscation, import wrapping or antidebugging stuff at all, but im pretty sure the exe isn’t patchable”. Hmm, a challenge :)

There are no classic anti-debug tricks nor anti-disasm tricks, only a good protection around the name/serial algorithm. The name/serial algorithm is very easy but it’s not the core of the crackme, the core is the protection that is used to hide the algorithm in order to make the reversing session a little bit hard.

The crackme is composed by two files, an exe and a dll. I started looking at the exe without luck so I passed to the dll which is the file to analyse. As I said before the file is not packed so everything is in front of my eyes. From all the functions one of them caught my attention: “check”. This function, which is called by the exe, contains the protector and the protection routine.

Protector
The protector is used to hide the protection routine. Let’s see how it looks like!

The ‘check’ function starts allocating a memory space from the process heap. After that the protector starts:

1000D5F4 mov ebx, eax ; eax is the start address of the allocated block of memory
1000D5F6 mov [ebx+14h], esi ; esi = 0×10003010 (xm.dll address)
1000D5F9 lea eax, [ebx+100h]
1000D5FF mov [ebx+1Ch], eax
1000D602 mov [ebx+0Ch], esp
1000D605 lea eax, [ebx+101D0h] ; Some little initializations
1000D60B mov [ebx], eax
1000D60D mov [ebx+4], eax
1000D610 mov esi, 0A642h ; esi = 0xA642
1000D615 mov eax, 555E0D3Ch ; eax = starting key
1000D61A mov ecx, 11h ; ecx = number of dword to decrypt
1000D61F add esi, [ebx+14h] ; esi = 0×10003010 + 0xA642 = 0x1000D652
1000D622 or eax, eax
1000D624 jnz short loc_1000D628 ; jump…
1000D626 jmp esi
1000D628 mov edi, [ebx+1Ch] ; edi = 0x1562B8, a pointer to a buffer inside the allocated block of memory
1000D62B add edi, [ebx+20h] ; edi = 0x1562B8 + 0×0
1000D62E add word ptr [ebx+20h], 8000h ; [ebx+0x20] = 0×0 + 0×8000 = 0×8000
1000D634 mov edx, [esi+ecx*4-4] ; Get 4 bytes from the dll
1000D638 xor edx, eax ; xor the bytes with the key
1000D63A mov [edi+ecx*4-4], edx ; Put the new 4 bytes inside the allocated block of memory
1000D63E rol eax, cl ; Change the initial key
1000D640 add eax, ecx ; Change the initial key
1000D642 loop loc_1000D634
1000D644 jmp edi ; The jump brings me at 1562B8

A decryption routine, nothing interesting you would say but you have to see the next part of code before saying something:

001562B8 MOV EAX,28
001562BD MOV DS:[EBX+68],EAX
001562C3 MOV ESI,0A69A ; esi = 0xA69A
001562C8 MOV EAX,106A109C ; eax = starting key
001562CD MOV ECX,11 ; ecx = number of dword to decrypt
001562D2 ADD ESI,DS:[EBX+14] ; esi = 0×10003010 + 0xA69A = 0x1000D6AA
001562D5 OR EAX,EAX
001562D7 JNZ SHORT 001562DB ; jump…
001562D9 JMP ESI
001562DB MOV EDI,DS:[EBX+1C] ; edi = 0x1562B8 points to a buffer inside the allocated block of memory
001562DE ADD EDI,DS:[EBX+20] ; edi = 0x1562B8 + 0×8000
001562E1 ADD WORD PTR DS:[EBX+20],8000 ; [ebx+0x20] = 0×8000 + 0×8000 = 0×0
001562E7 MOV EDX,DS:[ESI+ECX*4-4] ; Get 4 bytes from the dll
001562EB XOR EDX,EAX ; Xor the bytes with the key
001562ED MOV DS:[EDI+ECX*4-4],EDX ; Put the new 4 bytes inside the allocated block of memory
001562F1 ROL EAX,CL ; Change the initial key
001562F3 ADD EAX,ECX ; Change the initial key
001562F5 LOOPD SHORT 001562E7
001562F7 JMP EDI ; The jump brings me at 15E2B8

Well, as you can see the snippets posted above are really similar. The last 17 instructions are the same. Before making some considerations I’d like to show you some instructions from the next snippets:

0015E2B8 MOV EAX,DS:[EBX+C] ; Algorithm instructions
0015E2BE ADD DS:[EBX+68],EAX ; Algorithm instructions
0015E2C4 MOV ESI,0A6F7
0015E2C9 MOV EAX,37A878F4

0015E2F8 JMP EDI ; Jump to 1562B8

Some considerations:

- The snippets are executed starting from 2 different addresses, one from 1562B8 and one from 15E2B8; in this way you can’t see all the code but only two little pieces at a time. These are the instructions used to perform this trick:

ADD EDI,DS:[EBX+20]
ADD WORD PTR DS:[EBX+20],8000

- Every decrypted snippet is composed by 2 parts:
1. name/serial_algorithm: only few instructions
2. decryption_routine: instructions used to decrypt the next snippet
This is not totally true because looking at the trace log I’ve seen some exceptions, sometimes you can find only the decryption_routine and sometimes you can find a different decryption_routine:

001562B8 MOV EAX,2C3F
001562BD ADD EAX,DS:[EBX+14]
001562C0 MOV ECX,5
001562C5 XOR EDX,EDX
001562C7 XOR EDX,DS:[EAX+ECX*4-4]
001562CB LOOPD SHORT 001562C7
001562CD MOV ESI,8D89285A
001562D2 XOR ESI,EDX
001562D4 MOV EAX,C6C892A5
001562D9 XOR EAX,EDX
001562DB MOV ECX,8D898278
001562E0 XOR ECX,EDX ; ecx = number of dword to decrypt
001562E2 ADD ESI,DS:[EBX+14] ; You already know the code below this instruction
001562E5 OR EAX,EAX
001562E7 JNZ SHORT 001562EB
001562E9 JMP ESI
001562EB MOV EDI,DS:[EBX+1C]
001562EE ADD EDI,DS:[EBX+20]
001562F1 ADD WORD PTR DS:[EBX+20],8000
001562F7 MOV EDX,DS:[ESI+ECX*4-4]
001562FB XOR EDX,EAX
001562FD MOV DS:[EDI+ECX*4-4],EDX
00156301 ROL EAX,CL
00156303 ADD EAX,ECX
00156305 LOOPD SHORT 001562F7
00156307 JMP EDI

The code from 1562B8 to 1562E0 is used to obtain the value of ecx (which represents the number of dword to decrypt), the value comes out using some bytes inside xm.dll. I think the author uses this trick in order to make things a little hard;
suppose you want to write a little tool able to extract the needed instructions avoiding the decryption_routine; well with this new addiction you’ll still have useless instructions inside your code. Not so hard but usefull to confuse reversers.

- The decrypted code comes out from a simple xor instruction and the number of decrypted bytes depend on the value putted inside ecx register(it’s not always 0×11!).

Now that I know how the protector works I can try to read the protection routine. How can you read it?
The first bytes of the decrypted snippet belongs to the name/serial algorithm; to identify them you have to identify the decryption_routine and then extract the other instructions. You can’t step every instructions for sure! As I mentioned before an elegant method would be to write an application able to dump the decrypted code avoiding unnecessary instructions but it’s only doable if you are sure enough about the nature of the various decrypted snippets. Well, not impossible but requires an in depth analysis.
I solved the problem using the trace options available in OllyDbg. Once you have the entire log (saved on a file…) you can remove unnecessary instructions (i.e. decryption_routine) and read the protection routine.

Protection routine
It’s impossible to post all the code here because it’s too long, here is a little sum up:

1. Checksum over the bytes of the exe file. The crackme checks 0×2000 bytes starting from address 0×401000. I don’t know why it needs such a checksum because the exe file it’s not related with the protection, maybe I missed something…
2. Check over the serial, it has to be 19 bytes long with this form: xxxx-xxxx-xxxx-xxxx.
3. Sum of the four parts of the serial, F
4. Calculation based on the name’s bytes, R. I’m not interested in the algorithm because I’ll patch the dll but if you want to look at the calculation you have to decrypt the code starting from 0x1000E1B8.
5. Compare between the right (R) and the fake (F) value:

15E2c0 CMP DS:[EBX+64],ECX ; Compare R with F
15E2C6 JE SHORT 0015E2C9 ; jump means registered, this is what I want to patch!
15E2C8 INC EAX
15E2C9 MOV DS:[EBX+64],EAX

The algo is all here…

Patch the code
The final compare is encrypted inside the snippet which starts at 1000CDE4. Here is how the decryption works:

@loop:
mov edx, [esi+ecx*4-4] ; Get 4 bytes from the dll
xor edx, eax ; xor the bytes with the key
mov [edi+ecx*4-4], edx ; Put the new 4 bytes inside the allocated block of memory
rol eax, cl ; Change the initial key
add eax, ecx ; Change the initial key
loop @loop

It decrypts 4 bytes using a single xor operation, nothing else. To patch the instruction it’s not so hard, you only have to change a single byte. To register the crackme with any kind of serial (in the xxxx-xxxx-xxxx-xxxx form) I patched the byte at offset 0xCDF0, from 0x8D to 0x8C; the ‘je’ instruction becomes a ‘jne’ instruction.

Final notes
Pretty nice crackme with a good protector. The algorithm is really easy but I’m pretty sure about the fact that the algorithm is here just as a proof of concept. Orp attached the original script and the front end code at Woodmann’s forum; read it to see how easy is the algorithm (and how hard is to understand it :P)

Ciao!
ZaiRoN

Today I was checking a new crackme at crackmes.de; it’s written by Guetta and you can find it here: www.crackmes.de/users/guetta/r_keygenme/

The crackme is pretty easy but it has an anti-Ollydbg that I have never seen before. It’s really original I would say. Look at the picture below and see with your eyes:

Original anti Ollydbg

As you can see it’s hard to debug a program when you can’t see the source code! Let’s see how can you obtain the effect:

0040113A push 111h ; Point.y
0040113F push 14Eh ; Point.x
00401144 call WindowFromPoint ; Get the handle to the window that contains the point. The point is inside Ollydbg, exactly inside the code window
...
004011A8 push 90000h ; dwFlags: AW_BLEND + AW_HIDE
004011AD push 700h ; dwTime
004011B2 push eax ; hWnd returned by WindowFromPoint
004011B3 call AnimateWindow ; Enable the effects on the code window *hiding* the source code

The code doesn’t need additional explanation. Easy but original, very funny!

Some times ago my antivirus didn’t recognize a malware on my machine; the malware installed a keylogger and it did run silently in background for some hours. In general, you can discover the presence of a keylogger looking at the net traffic log or looking for some suspicious file name inside the task manager list but sometimes an application able to find out hooks will come in handy. At first I tried to find some informations browsing the net without luck. Hmm, no one has written such a program before? Is it possible or am I unable to use google??? I only got one usefull hint about the problem, nothing else.
Well, I decided to take a look at the problem. All my investigations are done under Windows XP/SP1.

Before starting with the analysis I want to show you the declaration of the function used to set a windows hook:
HHOOK SetWindowsHookEx(
int idHook, // Specifies the type of hook procedure to be installed.
HOOKPROC lpfn, // Pointer to the hook procedure
HINSTANCE hMod, // Handle to the DLL containing the hook procedure pointed to by the lpfn parameter
DWORD dwThreadId // Specifies the identifier of the thread with which the hook procedure is to be associated
);

It’s always good to know which parameters are passed to the function because you’ll have to deal with them later. Ok, time to start…

A possible starting point is represented by win32k.sys file, it’s everything inside it. Looking at the implementation of SetWindowsHookEx I’ve seen a call to HMAllocObject. This function is not really known but if you have ever read ‘Using Softice’ help file you surely read the phrase: “The routine HMAllocObject creates USER object types…”. Interesting, setting a bpx over the function I got the following informations:

.text:BF853AAB push 34h ; nBytes
.text:BF853AAD push 5 ; TYPE_HOOK
.text:BF853AAF push dword ptr [edi+3Ch] ; PTHREADINFO.rpdesk
.text:BF853AB2 push edi ; PTHREADINFO
.text:BF853AB3 call _HMAllocObject@16 ; HMAllocObject(x,x,x,x)

The function takes four parameters and the 3° parameter is related with the type of object that is created. In this specific case I’m dealing with hook so the type is TYPE_HOOK and HMAllocObject returns a pointer to a structure named HOOK, it contains general informations about the new object and it looks like:
typedef struct _HOOK {
ULONG hHook;
ULONG cLockObj;
PTHREADINFO pti;
ULONG rpdesk;
ULONG pSelf;
struct _HOOK *phkNext;
int iHook;
ULONG offPfn;
unsigned int flags;
int ihmod;
PTHREADINFO ptiHooked;
PDESKTOP rpdesk;
} HOOK, *PHOOK;

Fields:
- hHook
Handle to the hook procedure, it’s the value returned by SetWindowsHookEx and it comes from HMAllocObject
- clockObj
!?!
- pti
Pointer to THREADINFO structure of the process which sets the hook
- rpdesk
!?!
- pSelf
Pointer to this HOOK structure
- phkNext
Next structure in the hook chain
- iHook
Hook type (i.e. WH_MOUSE or WH_KEYBOARD). This is the first parameter passed to SetWindowsHookEx
- offPfn
Offset of the filter procedure, it is obtained by a simple substration between the address of the hook procedure and the initial address of the dll
- flags
HF_xxx flags (HF_GLOBALS, HF_LOCAL, HF_DESTROYED…)
- ihmod
Number of hooks set into the module
- ptiHooked
Pointer to THREADINFO structure of the hooked thread. If HF_GLOBAL is setted the pointer is setted to NULL because the hook works for every running thread
- rpdesk
!?!

As you can see the fields are not all explained, I’ll try to gain more informations.

Some of the fields are filled by HMAllocObject itself and they are non TYPE_HOOK related field; I mean, the HOOK structure contains informations about the hook you want to install (i.e. the hook type, the offset of the filter procedure) and informations not so strictly related with the hook (i.e. phkNext, pSelf). Since of all the work is done trying to understand if there are global hooks installed on the system I’m only interested in TYPE_HOOK related fields and these are:
1. pti
pti is really usefull because it gives me the possibility to access the process that has installed the hook. The first dword of THREADINFO structure is the pointer to ETHREAD structure which contains a pointer to EPROCESS structure. Once you have EPROCESS you can read the image file name (Imagfilename field) and the pid (UniqueProcessId) of the process that has setted the hook. At this point you can also read which dlls are loaded by the process or get any other usefull informations about it, especially which dll has the filter procedure inside. If you are not totally confident with undocumented structures you can even retrieve the informations using functions from Psapi library (i.e. EnumProcessModules/GetModuleFileNameEx to obtain a loaded dll…).
2. iHook
without it you won’t be able to know which hook was installed.
3. offPfn
only necessary if you want to know where the filter procedure is located at.

Starting from the HOOK structure I can retrieve all the needed informations about the HOOK but I need a fundamental information, maybe the most important one. Where can I find the HOOK structure? As I said before I only got an hint about the problem, it comes from an old thread at sysinternals forum (htt://forum.sysinternals.com/); I don’t remember the name of the user, thanks to him btw. The hint sounds like: “look at aphkStart”, nothing else. aphkStart is defined as:

PHOOK aphkStart[CWINHOOKS];

It’s an array of pointers to HOOK structure, one for each possible WH_xxx hook; the pointer at index ‘i’ is NULL if you are not under the hook. As far as I have seen there are two aphkStart arrays, one for local hooks (inside THREADINFO structure) and one for global hooks (inside DESKTOPINFO structure). To find out if a global hook has been installed you only have to scan the entire aphkStart array (the one inside DESKTOPINFO) looking for a not NULL entry, if you find it you are under a global hook.

The picture below represents a little sum-up. You start from the TEB of the current process, the process that check the installed hooks. When you have the TEB you can pass through some structures:
1. From TEB.Win32ThreadInfo you get THREADINFO structure
2. From THREADINFO.pDeskInfo you get DESKTOPINFO structure
3. If DESKTOPINFO.aphkStart[i] is not NULL you get HOOK structure of WH_i hook otherwise WH_i hook is not installed and you can check the next one, WH_i+1
4. From HOOK.pti you get THREADINFO structure of the process that has setted the hook
5. From THREADINFO.pEthread you get ETHREAD structure
6. From ETHREAD.ThreadsProcess you get EPROCESS structure
Inside EPROCESS there are many informations about the process, just read the necessary ones.

Way to installed WH_xxx hook

Follow

Get every new post delivered to your Inbox.