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 :)).
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