This lack is very usual (IMHO) in the Science-world. Sadly that cannot be taught in a lesson. I would like to try-to-solve this problem (mi granito de arena, vamos) writing different things ( I love to write things ), but is very hard for me to write good stuff in English (though i am improving ).
Well, the strainer. I've done it, though I had not enough time to do it as brilliantly as I would want. You know, I do everything the last day (casi me pilla el toro). I have hermitian operators pressing me :-).
Hope to see you (figuradamente claro) again. bye.
SiuL+Hacky ( Under your permission )
(Best view with fixed width fonts )
BUST OPENING MICROSOFT MONEYS (HOPE)
=============================
Well, here we are with two little stupid programs
from microsoft. History is really important in cracking, and after this
experience I am more convinced, as you will be after reading this. About
the searching, well, to find money 97 was easy, just some days before the
strainer was published. But money 94 is really hard to find in the web,
very hard (at least for me). Yeah, Yeah, I learnt in the process, but probably
my call provider is happier than me with this searching :-). I found all
ms money versions in the history but 3.0, very sad.
So I cracked first money 97. I know that this is not chronological, but as if you were in a good film you can imagine this first crack as a flashback of the whole story. One advise, the first tut is written in a way all newbies can understand it, so I decided to take very few things for granted. Like I didn't want to repeat practically the same, the second essay is shorter and I'm giving the solution and the way to follow ( but I don't go step by step ). I could say this essay is more of a teaching exercise than a cracking one, specially 'cause an experienced cracker is not learning any STATE-OF-THE-ART protection scheme with this couple of programs.
money 97
========
The first thing you do after installing it is looking
the big monster of money.exe, almost 5 Mb, What would do these programers
with the old spectrum ? They would be selling sand in some deserted island
probably. I ran it 'cause I wanted to fire the protection mechanism, but
it was not easy to be aware of it. You are advised to be over the 90 days
limit, but you can use the problem, so yo must get your fingers inside
this rubbish for finding some disabled part. Ok, the date in the database
must be inside the allowed limit (though it happen even if you are using
it in the first 90 days ). I decided to remove the sample sample.mny, and
the limit was restarted ( que chapuza tan impresentable ). So I knew the
current database has a lot to do with the (supposed) installation date.
+orc's clues about the GetLocalTime, leads us to the frequently-called function :46a308. Just have a look at it, we are not going to get further details (by now), 'cause I cracked it without understanding it perfectly, so I think if you can crack it without "deciphering" the encoding, it is somehow imperfect. Well, look at it, feel it, can you smell the coding routine ? Later I'll go through it:
:0046A300 83EC14
sub esp, 00000014
:0046A303 8D442404
lea eax, [esp + 04]
:0046A307 50
push eax
* Reference To: KERNEL32.GetLocalTime, Ord:00E2h
|
:0046A308 FF15B0006300
Call dword ptr [006300B0]
:0046A30E 668B442406
mov ax, [esp + 06]
:0046A313 6648
dec ax
:0046A315 66C1E005
shl eax, 05
:0046A319 6633442402
xor ax, [esp + 02]
:0046A31E 6625E001
and ax, 01E0
:0046A322 6631442402
xor [esp + 02], ax
:0046A327 668B44240A
mov ax, [esp + 0A]
:0046A32C 6648
dec ax
:0046A32E 6633442402
xor ax, [esp + 02]
:0046A333 66251F00
and ax, 001F
:0046A337 6631442402
xor [esp + 02], ax
:0046A33C 8B442404
mov eax, [esp + 04]
:0046A340 25FFFF0000
and eax, 0000FFFF
:0046A345 2D9C070000
sub eax, 0000079C
:0046A34A 83F87F
cmp eax, 0000007F
:0046A34D 7E1F
jle 0046A36E
:0046A34F B89CFFFFFF
mov eax, FFFFFF9C
* Referenced by a (U)nconditional or (C)onditional
Jump at Address:
|:0046A36C(C)
|
:0046A354 6601442404
add [esp + 04], ax
:0046A359 8B4C2404
mov ecx, [esp + 04]
:0046A35D 81E1FFFF0000
and ecx, 0000FFFF
:0046A363 81E99C070000
sub ecx, 0000079C
:0046A369 83F97F
cmp ecx, 0000007F
:0046A36C 7FE6
jg 0046A354
* Referenced by a (U)nconditional or (C)onditional
Jump at Address:
|:0046A34D(C)
|
:0046A36E 668B442404
mov ax, [esp + 04]
:0046A373 66C1E009
shl eax, 09
:0046A377 6633442402
xor ax, [esp + 02]
:0046A37C 6625FF01
and ax, 01FF
:0046A380 668B4C2404
mov cx, [esp + 04]
:0046A385 6683E91C
sub cx, 001C
:0046A389 66C1E109
shl ecx, 09
:0046A38D 6633C1
xor ax, cx
:0046A390 6689442402
mov [esp + 02], ax
:0046A395 83C414
add esp, 00000014
:0046A398 C3
ret
Ok, I agree, dead listing is more "sane", but I ( do you? )cannot crack it without softice. Who calls this function, and, as a result of it, fires the messageboxes ? What now I'm going to do is very easy, to follow the conection between the execution of this MesBox (stop now bad guy !) and the reason (some kind of comparison install-date and current date). This is really obvious, so good programers try to "hide" this conection. Nothing new, just the old back tracing. Many times it is not possible to do a dead back trace, so we must use Softice. Let's see what happen here ( you can trace also the identifier of the nag, as it's done in money 94 crack):
bpx MessageBoxA
Nothing happen, this is not our function. The nag window is fired with some other function. Take the dead list and inspect the imported funcions for some suspicious name:
bpx DialogBoxParamA
ok, it is our function. Write down the address and this is what we find in the dead list. Before showing it to you. What do I look for ? something like what we may call "bridge over the nag":
...
the famous cmp
jne GOOD_GUY
...
preparing nag window
...
call USER32.DialogBoxParamA
...
some lines (not a lot)
...
GOOD_GUY
and what i get in money 97 is:
( ... function called from one million places )
:0046D910 64A100000000
mov eax, fs:[00000000]; first line
... lines and lines with no near "cmp"
:0046D9B3 50
push eax
:0046D9B4 8B4510
mov eax, [ebp+10]
:0046D9B7 50
push eax
:0046D9B8 56
push esi
:0046D9B9 A1C8BD6200
mov eax, [0062BDC8]
:0046D9BE 50
push eax
* Reference To: USER32.DialogBoxParamA, Ord:008Ah
|
:0046D9BF FF15140B6300
Call dword ptr [00630B14]
:0046D9C5 668945EE
mov [ebp-12], ax
:0046D9C9 8B45E8
mov eax, [ebp-18]
( ... lines and lines )
Ok, we don't have what i told you, **** don't try to find something that do not exist **** , so look for variations from the basic scheme. Use softice to get the real caller and its neighborhood:
:00472817 668B442414
mov ax, [esp + 14]
:0047281C 6639842478010000
cmp [esp + 00000178], ax
:00472824 721C
jb 00472842; <- CAN YOU FEEL IT !!
:00472826 6A00
push 00000000
:00472828 A1D0306200
mov eax, [006230D0]
:0047282D 6A00
push 00000000
:0047282F 50
push eax
:00472830 68003F4D00
push 004D3F00
:00472835 685F2F0000
push 00002F5F
:0047283A E8D1B0FFFF
call 0046D910; <<< CALLING nag!!!
:0047283F 83C414
add esp, 00000014
* Referenced by a (U)nconditional or (C)onditional
Jump at Address:
|:00472824(C)
|
:00472842 668B5506
mov dx, [ebp+06]
Now you understand Softice is a must. We want to jump
for ever. If we look the registers window bx is zero at :47281c, so change
it:
old ----
:0047281C 6639842478010000
cmp [esp + 00000178], ax
new ----
:0047281C 663b9c2478010000
cmp [esp + 00000178], bx
I know it is comparing limit-date and today-date, but I don't know yet the details ( that is what I was telling before ). Now pull from the string. It is important to know how the program gets the installation date. There are two possibilities:
1) Get it once and store it (even with copies in memory).
2) Get it whenever you need it (even checking it
with some copies).
The second one is safer, but less common. Try the first one, which i am going to explain thoroughtly. Remember the code:
:00472817 668B442414
mov ax, [esp + 14]; <-- get limit day
:0047281C 6639842478010000 cmp
[esp + 00000178], ax;
:00472824 721C
jb 00472842;
When placed at cmp (for example) in Softice do:
bpm [esp+178] w; <-----> suppose ss:(esp+178) == ADDR1
disable it, restart money and enable it. Probably
it is a copy of a previous variable with the right value, then breakpoint
it and so on. If the variable
is located inside stack, softice will break one million
times, so use in this case:
bpm [esp+178] w if bplog
Then instead of breaking, the hit will be logged. But, think, we must stop the loggin when the var remains assigned to the right value, so USE ALSO:
bpx Last line known where the var has the right value (limit date)
for example bpx on any of the 3 lines of code above, then when it stops, look at the last match ( each one is logged by bplog ). More or less you'll find:
(... one million loggins)
loggin bp 1 bpm ADDR1 w dr3 if bplog (#137:472608)
Break due to 137:47281c
Ok, let's have a look to 472608:
:004725FC 668B8528020000
mov ax, [ebp+00000228]; <<< GET
:00472603 6689442414
mov [esp + 14], ax; <<< COPY
:00472608 E8F37CFFFF
call 0046A300
You can realize that softice logs the next instruction executed after the breakpoint. Continue our "searching-job". Edit our bpm and change it to:
bpm ebp+228 w if bplog
Restart Money 97 and ... what happen ? Softice crashes while loggin: WHY ? PLEASE WRITE THIS IN YOUR FACE, OR WHEREVER. I use to forget it and lose time wondering what's going on. Some actions should not be interrupted, one of them is DISK TRANSFER, so when your bpm crashes THINK THAT THIS MEMORY LOCATION IS WRITTEN DIRECTLY FROM A READ FILE OPERATION ( _hread _lread and so on). What does it mean ? the limit day is got from a file: yes, yes sample.mny. I told you.
Solution: bpx _lread ( look at imported functions )
enable it and land in the right _lread. Just after it is read, bpm (now for read-write operations ) the same location that crashes the program, and all the new copies the program may do afterwards (with the right value; actually, in money 97 it is copied once, and the original location is removed). If you trace them, they are gonna be compared before the nag (we know where) and before the second nag (when filling the database). Trace this location: ds:[628664] (the copy I told you), and try to enter an operation on 1/1/99. It'll break here:
:005C2C77 837D3000
cmp [ebp+30], 00000000
:005C2C7B 7421
je 005C2C9E
:005C2C7D 8B4D3C
mov ecx, [ebp+3C]
:005C2C80 668B81B5010000
mov ax, [ecx+000001B5]
:005C2C87 663DFFFF
cmp ax, FFFF
:005C2C8B 0F842F0D0000
je 005C39C0
:005C2C91 66390564866200
cmp [00628664], ax; <<< HERE !!
:005C2C98 0F863B0D0000
jbe 005C39D9; << jump bad guy
We don't want to jump. Look again at the reg. window and change it to:
:005C2C91 66391d64866200 cmp [00628664], bx;
Is it possible to jump always in 5c2c7b ?. Good question,
Try it !
Just one more thing, not very important. You cannot
use the program if the installation date is older than today (for example
you start the program on 2050, and want to use it forever back to the present,
just another approach). You just have to trace some calls to GetLocalTime,
and very soon there's a comparison with installation-date. Exactly here:
; in this moment ax == today
:00472882 6639442414
cmp [esp + 14], ax;
:00472887 768E
jbe 00472817;
So, jump always again. Change it to:
:00472882 663dffff
cmp ax, ffff;
:00472886 90
nop
:00472887 768E
jbe 00472817;
And use it like a tribute to our beloved (but lately
hated) nop.
Now we have it cracked. What happen with date encryption
? ok, let's see.
I'm gonna show what's going on ax and the memory
location, but first I have to tell you: I think it is absolutly stupid,
why they don't just take the days since 1970 ? Perharps, the programmer
wanted to tell us his/her born-date. this is ax:
ah
al
============= =============
| , , , | , , , | , , , | , , , | ----
> ax register
Now the routine step by step:
|
* Reference To: KERNEL32.GetLocalTime, Ord:00E2h
|
:0046A308 FF15B0006300
Call dword ptr [006300B0]
:0046A30E 668B442406
mov ax, [esp + 06]; << get month
|0,0,0,0|0,0,0,0|0,0,0,0|m,m,m,m| ----
> ax register
| month
( ... a month takes in the worst case 4 bits )
:0046A313 6648 dec ax
( it adjusted month info, because January is mounth 1 instead of 0 )
:0046A315 66C1E005 shl eax, 05
|0,0,0,0|0,0,0,m|m,m,m,0|0,0,0,0| ----
> ax register
|
We can know how many days are left in a year by:
month*30 + days, taking care that January is month number 0. Now in ax
we got the first part of the sum. Nota that in this case a month is gonna
have 31 days always.
:0046A319 6633442402 xor ax, [esp + 02]; << [esp+02]=ffff;
|1,1,1,1|1,1,1,M|M,M,M,1|1,1,1,1| ----
> ax register
|
I mean M as month xor f, or other way MMMM=(15 -
month)
:0046A31E 6625E001 and ax, 01E0
|0,0,0,0|0,0,0,M|M,M,M,0|0,0,0,0| ----
> ax register
|
:0046A322 6631442402 xor [esp + 02], ax
|1,1,1,1|1,1,1,m|m,m,m,1|1,1,1,1| ----
> [esp + 2 ] location
|
:0046A327 668B44240A
mov ax, [esp + 0A]; << get days
|0,0,0,0|0,0,0,0|0,0,0,d|d,d,d,d| ----
> ax register
|
( days info takes as much as 5 bits )
:0046A32C 6648
dec ax
:0046A32E 6633442402
xor ax, [esp + 02]
|1,1,1,1|1,1,1,1|1,1,1,D|D,D,D,D| ----
> ax register
|
:0046A333 66251F00 and ax, 001F
|0,0,0,0|0,0,0,0|0,0,0,D|D,D,D,D| ----
> ax register
|
:0046A337 6631442402
xor [esp + 02], ax
|1,1,1,1|1,1,1,m|m,m,m,d|d,d,d,d| ----
> [esp + 02]
|
( so we have how many days left this year, with months
of 31 days )
:0046A33C 8B442404 mov eax, [esp + 04]; << get year
|0,0,0,0|0,y,y,y|y,y,y,y|y,y,y,y| ----
> ax register
|
( I can't think of anybody using money needing more
than 11 bits )
:0046A340 25FFFF0000
and eax, 0000FFFF
:0046A345 2D9C070000
sub eax, 0000079C;
:0046A34A 83F87F
cmp eax, 0000007F; << year 2075 ?
:0046A34D 7E1F
jle 0046A36E ---|
:0046A34F B89CFFFFFF
mov eax, FFFFFF9C |
|
|
:0046A354 6601442404
add [esp + 04], ax |
:0046A359 8B4C2404
mov ecx, [esp + 04] |
:0046A35D 81E1FFFF0000
and ecx, 0000FFFF |
:0046A363 81E99C070000
sub ecx, 0000079C |
:0046A369 83F97F
cmp ecx, 0000007F |
:0046A36C 7FE6
jg 0046A354
|
|
|
:0046A36E 668B442404
mov ax, [esp + 04] <--|
( loading year again )
:0046A373 66C1E009 shl eax, 09
|y,y,y,y|y,y,y,0|0,0,0,0|0,0,0,0| ----
> ax register
|
:0046A377 6633442402 xor ax, [esp + 02]
|Y,Y,Y,Y|Y,Y,Y,m|m,m,m,d|d,d,d,d| ----
> ax register
|
( coding the year ? not yet )
:0046A37C 6625FF01 and ax, 01FF
|0,0,0,0|0,0,0,m|m,m,m,d|d,d,d,d| ----
> ax register
|
( more of stupid software )
:0046A380 668B4C2404 mov cx, [esp + 04]; << load year again
|0,0,0,0|0,y,y,y|y,y,y,y|y,y,y,y| ----
> cx register
|
:0046A385 6683E91C
sub cx, 001C
|0,0,0,0|0,Y,Y,Y|Y,Y,Y,Y|Y,Y,Y,Y| ----
> cx register
|
( now YYYYYYYYYYY= year - 28 = 1969, more absurd
)
:0046A389 66C1E109 shl ecx, 09
|Y,Y,Y,Y|Y,Y,Y,0|0,0,0,0|0,0,0,0| ----
> cx register
|
now the year has been stripped, now we have something like
( year - 28 ) % 128
What the hell is it ? They are coding somehow the
year information, the same way they did with "month" and "days", but now
it's not so perferct. For relating our "year", with "money97-year", first
think of a year with 512 days/year and second no Gregorian Callendar, year
0 is no more Jesus' born-date, Oh ! Sinners ! . Like the modified year
is divided by 128, this callendar is stable during 128 years before it
is reset, but for money 97 is enough. Now year 0 is 1948.
:0046A38D 6633C1 xor ax, cx
|Y,Y,Y,Y|Y,Y,Y,m|m,m,m,d|d,d,d,d| ----
> ax register
|
now we got the final compose. Call it STUPID_DATE
:0046A390 6689442402
mov [esp + 02], ax
:0046A395 83C414
add esp, 00000014
:0046A398 C3
ret
Now you'll agree is stupid. Well if you want to translate
from DATE of this stupid programmer born in 1948 to OUR DATE:
year = 1948 + (INT) STUPID_DATE/512
month = (int) (STUPID_DATE % 512 ) /31
year = (STUPID_DATE % 512 ) % 31
You may see there's a lot of 16 bits code. Is the protection taken from old 16 bits money 94 ? Very close, very close, not exactly, but they are very similar. I'm not gonna explain the other one like this, because there's nothing new. Here I'm giving you the code of money 94 coding (now that money97's is recorded in your mind ). It's up to you to delve inside it and realize it's practically the same I explained before.
:0081.0563 9AC008FFFF
call 0010.08C0
:0081.0568 83C402
add sp, 0002
:0081.056B 8A46F7
mov al , [bp-09]; << get month
:0081.056E 2AE4
sub ah, ah
:0081.0570 48
dec ax
:0081.0571 C1E005
shl ax, 05 << shift month
:0081.0574 3346FC
xor ax, [bp-04] << xor against 00 !!
:0081.0577 25E001
and ax, 01E0 << filter it
:0081.057A 3146FC
xor [bp-04], ax
:0081.057D 8A46FC
mov al , [bp-04] << month coded
:0081.0580 8A4EF6
mov cl , [bp-0A] << get days
:0081.0583 2AED
sub ch, ch
:0081.0585 49
dec cx
:0081.0586 32C1
xor al , cl
:0081.0588 251F00
and ax, 001F
:0081.058B 3146FC
xor [bp-04], ax
:0081.058E 8B46F8
mov ax, [bp-08]
:0081.0591 2D9C07
sub ax, 079C
:0081.0594 3D7F00
cmp ax, 007F << year 2047 ?
:0081.0597 760F
jbe 05A8
:0081.0599 836EF864
sub word ptr [bp-08], 0064
:0081.059D 8B46F8
mov ax, [bp-08]
:0081.05A0 2D9C07
sub ax, 079C
:0081.05A3 3D7F00
cmp ax, 007F
:0081.05A6 77F1
ja 0599
:0081.05A8 8B46F8
mov ax, [bp-08] << get year
:0081.05AB 2D1C00
sub ax, 001C << substract again
:0081.05AE C1E009
shl ax, 09 << shifting
:0081.05B1 8B4EF8
mov cx, [bp-08]
:0081.05B4 C1E109
shl cx, 09
:0081.05B7 334EFC
xor cx, [bp-04]
:0081.05BA 80E501
and ch, 01
:0081.05BD 33C8
xor cx, ax
:0081.05BF 894EFC
mov [bp-04], cx
:0081.05C2 8BC1
mov ax, cx
:0081.05C4 8B5E06
mov bx, [bp+06]
:0081.05C7 368907
mov ss:[bx], ax
:0081.05CA 8BC3
mov ax, bx
:0081.05CC 8CD2
mov dx, ss
:0081.05CE 8D66FE
lea sp, [bp-02]
:0081.05D1 1F
pop ds
:0081.05D2 5D
pop bp
:0081.05D3 4D
dec bp
:0081.05D4 CA0200
retf 0002
MONEY 94
=========
Three years before. First of all THANX A LOT Fravia
for the link, I was desperate. Do you think the protection is very different
? Of course not.
+orc gave some clues, but they were a little bit
tricky
1) In the version I cracked the addresses were slightly sled, for example:
* lesson 4.2 *
:0008.17CA 8B46F4
mov ax, [bp-0C]
:0008.17CD 3946F0
cmp [bp-10], ax
:0008.17D0 7246
jb 1818
* money 94 frech version *
:0008.17E2 8B46F4
mov ax, [bp-0C]
:0008.17E5 3946F0
cmp [bp-10], ax
:0008.17E8 7246
jb 1830
So, be careful and don't Bp without thinking ! Second and more suspicious, is the supposed crack ( taken from lesson 4.2 ):
********************* the hot code ********************
:0008.17CA 8B46F4
mov ax, [bp-0C]
:0008.17CD 3946F0
cmp [bp-10], ax
:0008.17D0 7246
jb 1818
* Possible Reference to Dialog: DialogID_0494
|
:0008.17D2 689404
push 0494 ;HERE! NOTICE OF EXPIRATION
:0008.17D5 685505
push SEG ADDR of Segment 0028
:0008.17D8 684C15
push 154C
:0008.17DB FF362C0A
push word ptr [0A2C]
:0008.17DF 6A00
push 0000
:0008.17E1 6A00
push 0000
:0008.17E3 6A00
push 0000
:0008.17E5 9A34019911
call 0005.0134 ;
********************* SUPPOSED +ORC CRACK ******************
instead of
:0008.17D0 7246
jb 1818
let's have
:0008.17D0 55
push bp
:0008.17D0 5D
pop bp
(nooping it)
************************************************************
Is it a joke or I don't understand anything ? Well it's a joke ( the addresses, the crack ... ). If you change it that way, the nag snaps always, so you must jump always, IT IS EXACTLY the scheme I told you ( bridge over the nag ) at the begining. So the cmp:
cmp limitday, today;
You just need to trace limitday and you have the crack. But what about today ? It is 16 bits, so no GetLocalTime, ... , or yes, they use the old-styled GetLocalTime, a service of Int 21h. In that moment I remembered a 1996 program: Secure Shell or something, that used a rather interesting function kernel!dos3call for getting the current date. Then I tried it and it was the one used in money 94 fv. Very funny, look at microsoft docs, now they recommend NOT TO USE this function. BTW, they use it a lot.
I'm not gonna explain the "tracing" process the way
I did with money 97, it is just the same thing. Ok, we are in front of
+orc's routine, but let's look some instructions before:
:0008.180D 9AD8053418
call 0081.05D8
:0008.1812 8BD8
mov bx, ax
:0008.1814 368B07
mov ax, ss:[bx]
:0008.1817 8946FE
mov [bp-02], ax
:0008.181A 8B46F4
mov ax, [bp-0C]; <<< get today
:0008.181D 3946FE
cmp [bp-02], ax; <<< some checking
:0008.1820 73C0
jnb 17E2
... if this secret checking is right jump
:0008.17E2 8B46F4
mov ax, [bp-0C] ; <<< get today
:0008.17E5 3946F0
cmp [bp-10], ax; << limitday ?
:0008.17E8 7246
jb 1830; <<< the code given by +orc
Play a little bit with the carry flag, and you'll realize that the first one checks limit-date with today+63. It is a way of checking today and installation date, of course today should be later or you'll be nagged as usual. Modify BOTH jumpings and jump always. These are the MODIFIED instructions:
:0008.181D 663bc0 cmp eax, eax; << new cmp
(... improve old money 94 with the powerful 32 bits technology )
:0008.17E5 3b7ef0 cmp di, [bp-10]; << second cmp
What else ? Ah, the database. So easy ( este crack ya lo podria terminar cualquier politico ), so easy that I cannot repeat it. Follow my instructions in money 97 (tracing back a value with the famous limitdate, taken from :0008.17E5, for instance). You'll discover that it is copied again in a fixed location, just like money 97 scheme, and you will land in the middle of this incredibly tough piece of code:
:0014.2B63 A1D664
mov ax, [64D6]; << get limit-date
:0014.2B66 3906D870
cmp [70D8], ax; << date entered ?
:0014.2B6A 7203
jb 2B6F; << below, jump good girl
:0014.2B6C E9970A
jmp 3606; << nobody fools microsft !
This way you just can have fun wondering a new way of changing the code. There are one million ways, here there's one:
:0014.2B66 3906d664
cmp [64d6], ax;
:0014.2B6A 7403
je 2B6F;
I would like you to enjoy these two programs, but
it's practically imposible to enjoy esta BOBERIA.
... JUST ONE MOMENT ... OHH, THE QUESTION
===========================================
A little bit more of Microsoft Crapping. Microsoft
Project 4.1, the last trap of our good old slick +orc. I'm giving you the
last part of the code given by +him (even his comms). I'll comment it beautifully:
:05167F6A E808CFEBFF
call 05024E77 ;CALL GetLocalTime
:05167F6F 66817DF4C007
cmp [ebp-0C], 07C0 ;is 1984?
:05167F75 722F
jb 05167FA6 ;go badflag
:05167F77 66817DF40108
cmp [ebp-0C], 0801 ;is 2049?
:05167F7D 7727
ja 05167FA6 ;go badflag
:05167F7F FF75F4
push [ebp-0C] ;save validyear
:05167F82 660FB645F7
movzx byte ptr ax, [ebp-09] ;pushday
:05167F87 660FB64DF6
movzx byte ptr cx, [ebp-0A] ;pushmonth
:05167F8C 50
push eax
:05167F8D 51
push ecx
============
Not a great thing. A flag is used for pointing the
naughty guys. It will be set at :5167fa6. Let's suppose we pass this first
test over. What else ?
============
:05167F8E E84EC10B00
call 052240E1 ;call here
:05167F93 663B45E4
cmp ax, [ebp-1C]
:05167F97 7D0D
jge 05167FA6 ;go badflag
:05167F99 668B4DE4
mov cx, [ebp-1C]
:05167F9D 662BC8
sub cx, ax
:05167FA0 66894DF2
mov [ebp-0E], cx
:05167FA4 EB06
jmp 05167FAC ;do not badflag
:05167FA6 66C745FE0100
mov [ebp-02], 0001 ;BAD FLAG !!!***
:no_bad_flag
:05167FAC FF75DC
push [ebp-24]
:05167FAF FF151C5C3C05 Call
dword ptr[053C5C1C];RegCloseKey
:05167FB5 EB25
jmp 05167FDC ;jump 2nd getlocaltime
======================================================
A mistirious call not commented by +orc. Je, Je.
Softice a little bit, and chan tata chan, TODAY-DATE ( coded in a way i
don't really care ) IS RETURNED IN AX REGISTER. And it is compared with...
LIMIT-DATE, of course. If you read lesson 4.2, the supposed holly "cmp"
was place later ... pretty suspicious. The flag will be set if you passed
over the time limit, but look, if you are a GOOD GUY you'll enjoy some
bonus-instructions:
; firstly it is important for you to know that at
this point
; [ebp-e]=0x5e and ax=today_date
:05167F99 668B4DE4
mov cx, [ebp-1C]; << load limit-date
:05167F9D 662BC8
sub cx, ax; << days to end
:05167FA0 66894DF2
mov [ebp-0E], cx; << save days to end
Thus, if you are a bad guy, [ebp-e] will remain with
0x5e, it is, YOU WILL BE IN YOUR FIRST DAY OF USING THE PROGRAM. Obviously
[bp-e] will not keep information about the timeout, so we just have the
flag.
==========================================================
... in the last snippet everybody jumped here
:valid_year_almost_everybody_calls_here
:05167FDC 66837DFE00
cmp [ebp-02], 0000 ;valid_flag?
:05167FE1 755F
jne 05168042 ;beggar off:unvalid something
:05167FE3 66837DF000
cmp [ebp-10], 0000 ;valid ebp-10?
:05167FE8 750E
jne 05167FF8 ;jmp unvalid_e10
:05167FEA 66837DEC00
cmp [ebp-14], 0000 ;valid ebp-14?
:05167FEF 7451
je 05168042 ;beggar
off,unvalid
:05167FF1 66837DF000
cmp [ebp-10], 0000 ;sure thatebp-10=0?
:05167FF6 7407
je 05167FFF ;continue
ifso
:unvalid_e10
:05167FF8 66837DEC00
cmp [ebp-14], 0000 ;check if e14valid
:05167FFD 7543
jne 05168042 ;no? be damned!
:valid_e10_and_e14
:05167FFF 0FBF4DF2
movsx word ptr ecx, [ebp-0E] ;
:05168003 66833D58192C0501 cmp dword ptr [052C1958],
0001
:0516800B 1BC0
sbb eax, eax
:0516800D 83E05A
and eax, 0000005A ;pretty obvious
:05168010 83C05A
add eax, 0000005A ;isnt it?
:05168013 3BC1
cmp eax, ecx ;HERE********
:05168015 7C2B
jl 05168042 ;beggar off
:05168017 66837DF21E
cmp [ebp-0E], 001E ;0x1E = 30
:0516801C 7F4A
jg 05168068 ;good guy jump
:0516801E 8D45F4
lea eax, [ebp-0C]
===============================
At :5168015 we had the suppossed holly "cmp", but
we got one before, which set bad-flag to 1, and if it's set, we'll jump
at :05167FE1 to the ugly world of nagg windows, and no further execution
of this second holly "cmp". But if we do not jump (setting bad-flat to
0, as +he tells), this second "cmp" will be good always, 'cause remember
that we shall be ALWAYS in our first day.
If we want to use anyway the failed crack, you should
change also the first cmp/jge located at :05167F93.
================================
I don't know. Were they trying a NEW protection scheme ? Something BIG ?. Sorry the only BIG, HUGE, thing around is Msproject itself.