TARGET : Xorcise 2 by Crudd
AUTHOR: Extasy [ID]
SKILLS NEEDED : Reversing + little ida
TOOLS:     Softice
                      Ida
                      Hiew



 
 
 
Introduction

Hello Everyone !
I'm coming this time to reverse one more time a Crudd re-me. This time it's getting serious, we have to face a dialogbox creation and some encryptions.
 


 
First Step

 
 

Ok, take back your reverser notebook and, goooo !Take a quick look at the task in front of us. Mmmmh ok, as the readme says, you have to implement the decrypt function. That's all ;-). But what do we REALLY need to do ?
-Find a way to input the decrypting key
-Take the data to decrypt
-Decrypt :)
-Put it back on screen.
This time we will make everything as it is te ached at school. First of all, we have to find a place for our code. Fire Procdump.We are lucky, there is a cave at the end of the .text section ! We have a space of 178 bytes exactly. Let's assume (hope ?) it will be enough. So adjust the Virtual Size of the section to 1200, or, even better, to 1300, so that we will be able to put our variables after the code. As you're in procdump, change the .text characteristics to E0000020, so we will be able to store our data there. So, we have our space now.
I try to insist on the point that planning everything before you start to add code is VERY IMPORTANT. So your paper near the hand, dissassemble the file and try to grap some info about the program. Here's what i find :

-The dialog box that is used is called by the CreateDialogParamA, and is named DLGWIN. It's DlgProc is at 4012A 0.
-We can use GetDlgItemTexta to get the user key. THe pointer is at 403088.
-At [ebp-04], there is the edit handle, into the main message loop.
-We can then use GetWindowTexta to get the window text. The pointer is located at 40307C.
-We can use SetWindowTexta. Pointer at 4030B0.

Then i had little trouble with the decryption routine, it should be located just after the GetWindowtext at 4019F7. But, at dissassembly it weren't :-(. I think crudd decrypts it at runtime. Just as info, it is xored by 15 (simply try to xor the first decrypted byte by the encrypted one, you will get 15h everytime :)).

Here we could dump it, or decrypt it, and then paste it into our place, but we are space limited (remember, only 178 bytes). So we will fill the places where the program normaly puts the data. Bpx Getwindowtexta in softice, and note this too :
404158 = pointer to the Data to decrypt
404164 = Key lenght
40415c = Key
We have now the decryption routine.

But, if you're one of those perfectionnist guys (or girls), you can create a small decrypting function for ida. As i think that a lot of you don't know idc, the ida "macro"  :-), i'll explain it. Cre ate a small file named decrypt.idc into the \idc directory in the ida path. In this file put the following :

#include <idc.idc>
void decrypt()     //we declare the function
{
auto from,size,x,y;            //we declare 2 variables

from= 0x401ce6;                //we initialize the address and size
size=0x40;
while (size>0)                      // we create a small loop that will xor every byte, one by one
{
x= Byte(from);                    // we take one byte from the first argument, from, wich is the pointer
y=x^0x15;                           //we xor it by 15h
PatchByte(from,y);           //and we finally patch it
from=from+1;                     //we increase from, to point the next byte
size=size-1;                        //and decrease the size
}
}

Then all we have to do is to load it by presssing F2, and then double-clicking on decrypt.idc. Click on the whells then. Next press Shift-F2, and then type into the window "decrypt();", to run it. Now everything is decrypted, and it looks really better :).


 
Second Step

Now that we're back from this little matter, we can continue to our main goal : REVERSING THIS !. But, eh, didn't you notice something ? I forget my api list ;-)). Let's do it now !

GetDlgItemTexta             403088
GetWindowTexta            40307C
SetWindowTexta            4030B0
CreateDialogParamA     4030A0
GlobalAlloc                       403044 (hm, it's not really globalalloc, but it does the same, and it's already used :))
GlobalFree                        403040 (same here)
EndDialog                         40308C

Now everything is clear into your mind, no ? For myself, at this point i could see the function before writing it. One more note : we have to copy the beginning of the existing messageloop. Run hiew, and, let's CODE !
You start at 4020BA:

push 1000
push 0
call d,[403044]                            Call GlobalAlloc to create a big enough place
mov [404158],eax                      Store it in the "good" place push 1000
push d,[404158]
push d,[404010]
call d,[40307c]                           GetWindowText
push 0
push 402133
push d,[404010]
push 404020
push d,[404008]
call d,[4030a0]           &n bsp;              CreateDialogParam
mov [40401c],eax                    Here too we need to fill the "good" place, the one that is used after

At this point i recongnize i were really lost. I saw that the decrypting routine i wanted to use was encrypted !! (remember, we decrypted it in ida). So, i thinked of a way to locate the decrypting routine. Wait ! Did you read the whole readme.txt ? he said it was just a little harder. Try to dissassemble the easy one : it's not encrypted ! Now we can easily detect the decrypting routine : A fie compare !!!!!! (don't forget to take two "virgin" copies). Hum, it's not that easy, but with a little of good sense we can identif y that around 1490 something misses into the easy one (0 filled). Go into hiew, and try it. We're right ! it's a typical decryting routine. We can even recognize our xor 15 (yes, we could have researched this). So redirect the program to this place directly, after the CreateDialogParam call.

push 40208a
ret

This time it's ok. And this routine even uses ShowWindow ! (one more thing we won't have to do). What's left ? The message loop (no, it's not self-created  ;-)). We have to put it at 402133.

push ebp
mov ebp,esp
add esp,0fffffeb4
cmp d,[ebp+c],111            Is it WM_COMMAND ?
jnz 158b
cmp d,[ebp+10],7d1         Is it the Ok button ?
jnz 158b
mov edi,[404158]              Search the signature
lea esi,[4021e0]
mov ecx,10
repnz cmpsb
jnz 156a                               If there is a signature, add 10h to the pointer (del it)
add d,[404158],10
push 8
push 40415c
push 361
push d,[ebp+8]
call d,[403088]                    Get the user key
mov [404164],eax               Get the key lenght
call 10e6                              Call the decryption routine
jmp 158f                               I coded this jump so that the 2 jumps at the beginning won't be long jumps :)
leave
ret 10
push 0
push d,[ebp+8]
call d,[403 08c]                    EndDialog
push d,[404158]
push d,[404010]
call d,[4030b0]                    SetWindowText
push d,[404158]
call d,[403040]                    GlobalFree
leave
ret 10

One more target reversed ! Oh, don't forget to put the signature (the 16 bytes)  at 4021e0 or it won't delete it. You could ask me why i search for the signature, as it should always be here, and you may be right, but it's better to prevent all errors :)


 
Conclusion

It has been a real pleasure to reverse one more time a Crudd reverseme. There was a lot of innovations here, like the 2 levels, the code encryption, the dialogbox to re-create. If only all the reversemes were like this one, there would be a lot more reversers ! :-).

Thanks goes to :
Crudd, [ID], SantMat, amante4,MagicRaph,Edy,Tam,C_DKnight,ep-180,promethee,V-Rom,to everyone from #C4N, #immortaldescendants
Et à tous ceux qui reversent en V.F !

Mail me for any question,comment, or to send me another re-me ;)
extasy@netcourrier.com