Log in

View Full Version : uic strainer...


ZaiRoN
August 21st, 2002, 17:35
hi to all!
it's time to work on something hard!!!

this is a strainer made for an italian reversing group: UIC.
the first line of the attached file says:
"This crackme is simple, you must only arrive to Congratulation Box..."
attention, don't believe in him!

inside you'll find many interesting things: seh, interrupts modification, anti-sice stuff, and so on.
it isn't a classical name/serial crackme, it's like a puzzle...

as i said before it's not for newbies but everyone is well accepted and experienced fellow(s) will help you
i thought the project can be very useful in order to improve our knowledge

needed literature: intel manuals (especially #3)
http://developer.intel.com/design/pentium4/manuals/

good luck & have fun
ciao,
ZaiRoN

ZaiRoN
August 22nd, 2002, 22:32
hi!
i don't know how many people are working on this target; anyway, here is a little help in order to start play with the crackme.

at first, the main problem (i think) is that the crackme crash (or block) your machine if you set breakpoint.
the problem resides in the initial part of the proggie where some interrupts handler are changed.
here is some code:
Code:

00401000 call GetVersion ; it doesn't work on NT system
00401005 cmp eax, 80000000h
0040100A jnb short near ptr loc_401071
...
00401071 call near ptr byte_40167F ; modify int3 (breakpoint exception). new int3 handler = 401755

the first important call is the one at 401071:
Code:

0040167F mov eax, 401755
00401684 mov word ptr ds:byte_402721, ax
0040168A shr eax, 10h
0040168D mov word ptr ds:dword_402727, ax
00401693 sidt ds:qword_4026C7 ; get base address of idt (interrupt descriptor table)
0040169A mov ebx, dword ptr ds:qword_4026C7+2 ; ebx points to idt base address
004016A0 add ebx, 18h ; ebx points to int3 handler (the original)
004016A3 mov edi, 4026CDh ; where to save the original int3 handler
004016A8 mov esi, ebx ; esi points to int3 handler
004016AA movsd ;
004016AB movsd ; save the original int3 handler
004016AC mov edi, ebx
004016AE mov esi, offset byte_402721 ; esi points to the new int3 handler
004016B3 movsd ;
004016B4 movsd ; change the int3 handler. the new handler is at 401755
...

ok, in this way the crackme can do everything when an int3 in raised! (look at 401755...)
how to deal with this?
hmmm...personally i don't allow the crackme to execute the call at 401071 and when an int3 is called, i change the eip to the right handler: 401755.

as said before, this is not the only int that is modified but you can apply this method to the others (remember to sign the new handler(s)!)

well, someone want to continue?

regards,
ZaiRoN

Kayaker
August 25th, 2002, 06:32
Nice job finding this one Zairon! It has a few, er, twists and turns... Interesting choice of interrupts, INT 9, INT 18.., I've taken the tact of ensuring NONE of the interrupts in the IDT get hooked by jumping past the series of Calls which hook each INT. This may backfire on me because one of them may be needed to find the correct route through.

I've directed the code past a seemingly bogus CreateFile call, and a section which would have wiped out large portions of code with garbage, to the "obvious" _lopen / _lread of a key file. From there it seems to branch to 3 more trouble spots depending on the results from the keyfile, it either Rehooks INT 4 (don't think it's unhooking it, especially since it doesn't unhook the IDT on exiting), or executes a BOUND instruction (equivalent to an INT 5), or runs directly into a bunch of INT 4 instructions.

There is a small trick to getting _lread to return successful, can you see it from this code?

:00401404 push 1
:00401406 push offset aBonzokey_key ; "BonzoKey.key"
:0040140B call _lopen
:00401410 push 1Eh
:00401412 push offset unk_0_40214D
:00401417 push eax
:00401418 call _lread
:0040141D mov eax, ds:dword_0_402152+2
:00401422 mov ebx, ds:dword_0_402152
:00401428 div ebx
...to checks

I haven't checked, but I'm *hoping* a correct keyfile might decrypt some code which jumps to a good section. Also, it's possible one or more of the new Interrupt Service Routines (ISR's) that the program installed for Interrupts 2-5, 9 or 18, may contain some code which also decrypts an important section. Mind you, all the ISRs look a little odd, they may be just to cause crashes. The Softice command 'IDT' will display the Interrupt Descriptor Table and will show the addresses of the new ISRs installed.

There's couple of interesting things in this. It begins with an SEH installation and the sequence of IDT hook calls just before the first message box, and then goes on to load a small dialog box. When the 'register' button is clicked there is a decryption of a binary string at 402028h which *should* decrypt to a valid filename for a CreateFileA call one would think. However it just creates another binary string which can't be converted into ascii.

:00401393 push offset aC51f6I ; "c+5¦1f!6|i+"
:00401398 call CreateFileA

If you DID allow CreateFileA to be called, then it goes on to do an interesting wipe of 2 code sections. It uses the RDTSC (Read Time Stamp Counter) command as a random byte generator to use as an xor value for wiping code. RDTSC returns the number of clock cycles since the CPU was powered up or reset as a 64-bit count in EDX:EAX. It can be used for testing the relative speed of a code section between two RDTSC commands. Here it just gives a random xor value in AL. This code is used to wipe a section at 40130Ah and 4013D4h, which includes the keyfile routine. Nice trick for wiping a section of memory.

:004013A8 xor ecx, ecx ; clear counter
:004013AA mov ebx, 40130Ah ; address to start overwriting

:004013AF RDTSC ; returns a dword in eax
:004013B1 xor [ebx+ecx], al ; xor with byte [address + ecx]
:004013B4 inc ecx
:004013B5 cmp ecx, 1FCh ; overwrite 1FCh bytes
:004013BB jnz short loc_0_4013AF

:004013BD xor ecx, ecx
:004013BF mov ebx, 4013D4h
:004013C4 RDTSC
...


The INT 9 is particularly fun, giving an impressive video hang, I get a mottled gray background with a single blank icon square around where the mouse cursor used to be ;p I think the keyfile needs a closer look to see if it's really part of the protection.

My $.02 for now,
Kayaker

ZaiRoN
August 25th, 2002, 16:39
Hi Kayaker!
your post are always interesting.

> There is a small trick to getting _lread to return successful, can you see it from this code?
hmmm...no.
_lread *should* work fine, why not!?!
you have to pay attention on the 'div ebx' instruction.
infact, if you don't put right values in the BonzoKey.key you can have a 0/0 operation that will raise exception...

> I think the keyfile needs a closer look to see if it's really part of the protection.
i think that the keyfile is here only for kidding us!

- if the CreateFileA function find the keyfile, as Kayaker said, we will reach this piece of code:

:004013A8 xor ecx, ecx
:004013AA mov ebx, 40130Ah
:004013AF rdtsc
:004013B1 xor [ebx+ecx], al ; EXCEPTION: C0000005h write memory violation

the .CODE section has only 'readable' and 'executable as code' attributes but NO 'writable' attribute.
so, the instruction in 4013B1 will raise an exception.
put a bpx on 401AA5 (the entry point of the exception handler) and see what happen when you step the xor instruction.

... exception handler...
:00401ADC cmp eax, 0C0000005h ; write memory violation
:00401AE1 jz short loc_401A81 ; our jump...
...
:00401A81 mov ds:byte_40216C, 7Fh
:00401A88 mov ds:byte_40216D, 0C0h
:00401A8F mov eax, offset loc_401A99
:00401A94 xor word ptr [eax], 7777h ; damn! another write memory violation!!!

this cause a recursive jumping from this snippets and the seh handler.
the problem is that i really don't know how to exit from this jumping sequence !?!
and, it doesn't have much sense !?!


- if the CreateFileA doesn't find the keyfile, you'll reach a piece of code where some interrupts are called.
those are int9, 3, 4...
maybe this is the right way but who knows!?!


ok, this is a simple description based only on ida dead listing because momentarily i don't have sice/olly...
don't know what do you think about the keyfile but this is my thought...
i'm waiting your thought/suggestion/comment

regards,
ZaiRoN

mike
August 25th, 2002, 18:40
Quote:
The only limitation is that you can't put a jump directly to MessageBox routine
this is not valid ))
So do an indirect jump, or a push/ret, or do a direct jump to just before the MessageBox routine, or write your own crackme puzzle that has the same messagebox and send it back or...

Kayaker
August 25th, 2002, 19:54
Heh, I don't know which is the right door. I've traced through one of the 3 or 4 directions the _lopen keyfile routine could take, but I'm not holding out any hope on an easy solution there. The routes just seem to lead to bad code with nonsense decryptions. The CreateFileA routine might be used to open a keyfile if you changed the code to point to a valid ascii filename, but it doesn't seem to matter because success leads directly to CloseHandle anyway.

Why _lread might fail...? Permissions?


After the CreateFile routine is the RDTSC routine.

:004013A8 xor ecx, ecx
:004013AA mov ebx, 40130Ah
:004013AF rdtsc
:004013B1 xor [ebx+ecx], al ; EXCEPTION: C0000005h write memory violation
:004013B5 cmp ecx, 000001FC
:004013BB jne 004013AF

Interestingly, the EXCEPTION doesn't occur on a simple memory write. You can trace through this code and see the addresses from 40130Ah change, but (40130Ah + 1FCh bytes > 004013AF) and eventually the rdtsc code itself gets overwritten as it's processing the loop.


I don't even have the programs SEH handler enabled, as you've shown Zairon, it doesn't seem to be much use either. Not too sure... I think it's time to look at the problem backwards and see if the goal of the challenge (show a Congratulation Box), can be found and tied to the earlier code. It may require a partial decryption or other patching, but you could use one of the hooked interrupt routines or the SEH to run some of your own code. There is a bit of code before the _lclose routine that looks interesting...


Kayaker

evaluator
August 26th, 2002, 19:30
Hello!

crackmes are not my hobbie, but I dld this crackme just for look.

My Q is:
this prog has bug (it crashes on w98se),
or it is speacially done & we must correct prog?

Kayaker
August 26th, 2002, 19:36
Hi evaluator, Yes, this is part of the challenge it seems.

K.

ZaiRoN
August 26th, 2002, 19:58
Hi evaluator!
directly from the rulez.txt attached file:
"Ah.....don't worry if it will crash :P"

bye,
ZaiRoN

Bengaly
August 27th, 2002, 07:57
Well it doesn't run on Win2000,
it says:
Quote:
Questo progrrama non puy essere utilizzato su sistemi windows NT"


to fix this, just change the cmp eax,ur version

original:

call GetVersion
cmp eax, 80000000h
jnb short near ptr loc_0_401070+1
push 20h
push offset aWrongSoVersion ; "Wrong SO version!"

patch:

well, breaking at offset 600 with INT 3 will led us fetch the Version, in here at least i get: 0893005h, so Changing the
80000000h to 05009308 (Win2000 professional) will fix this small problem, and bring us to the evil calls with lotsa crashes
cya

Bengaly
August 27th, 2002, 09:17
here is a runnable fix of the file.
its tested on my machine (Win2000 & win98se), i guess mabye it will crash on the GetVersion, but u only need to change the cmp eax,ur version (if thats the problem).
i guess its not so hard to fix this crackme in order to run it properly, but if someone can't, just explore my small fixes.

-> ah i just checked on win98se (dual boot), the fix is working there too..so i hope u wont get any probs .
-> (btw, the register button crashes in win9x, is that supose to be a part from the protection?..i dont know yet, but on win2000 it just close the crackme when pressing the register button)

cya
Ben

nikolatesla20
August 27th, 2002, 14:03
I guess it's protected, eh? When it doesn't even run worthwhile, and uses os specific trix.

Whatevah. Talk to the hand, man.

-nt20

Bengaly
August 27th, 2002, 14:12
its not protected with any packer or alike, its just use some damn jmps from place to place and using ints to kick ur ass or some faults which raise exceptions,
i would think that the readfilea is a decoy since it always gets -1.
i guess in order to fix ur route u will need to make some inline patches, but that just a though.

ZaiRoN
August 27th, 2002, 15:20
Hi all!!!

Ben:
maybe it works well on win2k but i suggest you to work on win98 system only.
the italian message sounds like "the program cannot run on windows NT system" ... but you should already know this

for all:
as said in the first post, this crackme is like a puzzle!
there are many interesting things inside but the main problem is: how i could join this things together!?!

perhaps you know already these information; however, it's here some points on which being able to discuss together:

- run the crackme with filemon enable. the crackme close filemon (and crash...)
so, the crackme detect filemon !?!
there are many ways to find if filemon is still running but the most general is the one that use the createfile approach.
i guess if the CreateFile function is used for this and i guess if the bytes from 402171 are here for taking "filevxd.vxd"...

- starting from 401607 there is a decryption routine. it decrypts 68 bytes starting from 401026. it used a double xor-layer but i'm not able to find the right key.
this piece of code is reachable from two different point:
1) from the jump relative to the invalid_opcode error code.
2) from the lines above if you decrypt well the two bytes at 401605. it *should* be a checksum or something like; look inside the call at 4015C4...

- when i was looking at the disasm code, i was thinking about this imaginary flow execution:
the first call of the CreateFile fails because the filename has non sense; then (after some code...) 68 bytes from 401026 are decrypted.
after the execution of the 68 new bytes_code we will jump down directly to the CreateFile function.
the second call of the CreateFile is used to detect filemon (and the filename is "filevxd.vxd"
if the filemon is not found we will arrive at _lread function and ...

these are only my considerations that obviously could totally be mistaken but who can say it !?!

Kayaker: maybe we have to take the two doors

regards,
ZaiRoN

Bengaly
August 27th, 2002, 16:26
i ran file mon with the crackme and there was no crash ;P
and it didn't look for any bonzokey.key, but that just over win2000 and also the crackme works fine here..

evaluator
August 27th, 2002, 21:34
My suggestions:

1. we should change to WRITBLE code section.
2. There are INT01s & there is code for change INT01 handler(4018FF), but it not executed.
This is first reason for crush w98-system.
IF assume: this is trick, so when you meet INT01, you also should execute
his own handler (40193C).

ZaiRoN!
We need more Rules for game called PUSSLE or POSSIBILLITES will eat us!

Bengaly
August 28th, 2002, 19:31
Face it might evaluator.
u can't do it

evaluator
August 29th, 2002, 10:54
what if it is like "white joke"?

I traced inside all INT handlers & found many interesting things,
but can't force to right decrypt code at 401026.. later about it.

Now anyway, lets try "arrive to Congratulation Box".
But where is code for it??
Yah! I guess it starts at 401261 & 24 bytes are crypted.
Why I think so!?
I just calculated how many bytes is need for MessageBox routine + 1jump
& this code is also 24 byte

Lets write at 401261:

6A20--------with ICON please
68C4254000--Gooooooood!!!!!!!!
68D7254000--Oh Yeah! I'm registered now!!!
6A00
E848A00000 -call MessageBoxA
E9C1030000 -jump to Full exit routine with IDT restoring

so we need also:
1.change jump at 40125F to no-jump (EB44>EB00)
2.nop 2 byte at 40199A for avoid crash

Hope it helps for true UncrackMe.

evaluator
August 29th, 2002, 22:03
YUUUUUUU!

Unbeleaveble Job Done!

1. all crypted(xor-ed) code will decrypted & then patched
2. SEH-handler remanaged
3. XP(nt)-compatible

Who CAN!? Who can'T???

evaluator
August 30th, 2002, 16:14
OK, Final Version uploaded(Major Update.

So what now?
Should I somewhere send my un_pussled work?
Or it is already done??(Zairon, I kill you, if so~:0)

ZaiRoN
August 30th, 2002, 16:35
have you ever slept in this days!?!

i have a little question for you:
how you have made to find the eight bytes from 40216B ?

byebye,
ZaiRoN

evaluator
August 31st, 2002, 04:35
Hi, ZaiRoN!

about bytes: in disassembly I found referenses to these bytes,
but only 6 are valid. Problem is byte 40216F (63 seems wrong)
& then for byte 402171 (becuase it calculated from 40216F).

Later about how I found..
First answer on my previous Questions, please!

ZaiRoN
August 31st, 2002, 10:02
Hi evaluator !!!
Quote:
First answer on my previous Questions, please!
do you want to know if someone has just solved this crackme?
yes...but i think the are no tutorials yet on the net.
anyway you can send your solution to Quequero (people are always happy when someone break his crackme )

regards,
ZaiRoN

evaluator
September 2nd, 2002, 19:22
eh, you kill me..

OK, I performed BruteForce analyze in Mind about what final XOR can be
for range 401026-40106A.
Using HexWorkShop I exported this range:
63 84 89 E8
C2 82 8B B7
8E 8D 23 B5
F5 96 E8 A8
43 44 32 95
BB 31 12 D8
D0 F7 A8 CE
05 B5 38 38
F1 7E 12 DD
D0 F7 A8 99
DE BD 2B 69
C6 34 51 B0
B7 42 9B 61
78 C2 BA E8
C2 86 AC A2
41 76 AC 2B
3B AF DD 5D

then I sad to myself:
most used byte in code is 0h,
so in each column I choose 2time repeated byte & I have this variant:
C2 -- A8 A8

then I XORed range of code with it & it looks very like as normal code!
Some tries and I get second byte.. so summary XOR is:
C2 B7 A8 A8

backward XOR this with bytes from 40216B-6E & I have correct 2 bytes for 40216F & 402172
VIVA, ITALIA!

Mutch easy was range MessageBox range, because I first wrote my code & then according
to this found XOR.

So final 2 Q I have are:
1. IF my XORs are right, authors before XOR-ing "damage" that code, so I patch it.
(Or my XOR is incorrect??)

2. Is no-bruteforce way for find correct byte 40216F?

ZaiRoN
September 3rd, 2002, 19:13
Hi evaluator.

>...(Or my XOR is incorrect??)
your 0xA8A8B7C2 xor value is right. i agree with you that some byte has been modified after the xor.

i have take a look at your modified file. you have added/removed several lines of code.
is this the right way!?!
it's strange but, is a *massive patch* necessary?

i havn't still tried but i'm thinking to change only few bytes:
- the few bytes that were changed by the author in the (two) encrypted code. i don't know yet the right values...
- bytes from 402133/40213A: 23 1F 4C 3A E1 A8 E4 92
- bytes from 40216B/402172: 00 CF 06 7A C2 78 AE D2
i must say that without your work (maybe) i wouldn't be never successful to find those values...thx!

anyway, what do you think? it could work?
i'll try in the next days...

regards,
ZaiRoN

evaluator
September 3rd, 2002, 20:27
massive patch??

as I wrote, SEH-handler is damaged so I added my SEH-manager (103byte)

in 1st dexored section I patch 5 byte, in 2nd- 4 byte.

OK, make your job & lets compare.