Cracking Security Administrator For Windows 95/98 v1.3 by douby^dread
First of all, I'd like to say that I really like Tornado's approach
of helping newbies with increasing their cracking skills. That's why
I decided to help him with this project of his ;-)
When you run Secagent, the first thing you'll notice is the a window
asking you for the serial number.. It doesn't ask for a name or
company or something. So the serial is probably hardcoded or sumphing
like that...
Let's enter a wrong serial... What you get is a messagebox whining
about a wrong registration code.. Now what ? We could do a couple
of things first of all we could do lil'bit of fooling around in soft-
ice, setting some breakpoints and stuff or we could load the program
in w32dasm and take a look at the dead listing first... The latter
is the approach I usually prefer.. So guess what I did first eh ?
Yeah dudez, you got it right, I disassembled the program in w32dasm
and took a look at the string table.. And boy, there were a couple of
nice fish swimming around in there ;-) "Sorry this registration code",
"Registration has successfully".. Double clicking on one of these
babes will get you here:
:00471C64 8B55FC mov edx, dword ptr [ebp-04]
:00471C67 8BC3 mov eax, ebx
:00471C69 E842B0FFFF call 0046CCB0
:00471C6E 84C0 test al, al
:00471C70 7438 je 00471CAA ;if al == 0 wrong serial
:00471C72 8B4DFC mov ecx, dword ptr [ebp-04]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00471C0E(C)
|
:00471C75 BAEC1C4700 mov edx, 00471CEC
:00471C7A A1B4584700 mov eax, dword ptr [004758B4]
:00471C7F E8E07FFFFF call 00469C64
:00471C84 B201 mov dl, 01
:00471C86 A1B4584700 mov eax, dword ptr [004758B4]
:00471C8B E8B87FFFFF call 00469C48
:00471C90 6A40 push 00000040
* Possible StringData Ref from Code Obj ->"Information"
|
:00471C92 B9F01C4700 mov ecx, 00471CF0
* Possible StringData Ref from Code Obj ->"Registration has successfully "
->"completed!"
|
:00471C97 BAFC1C4700 mov edx, 00471CFC
:00471C9C A1C0404700 mov eax, dword ptr [004740C0]
:00471CA1 8B00 mov eax, dword ptr [eax]
:00471CA3 E85C50FDFF call 00446D04
:00471CA8 EB18 jmp 00471CC2
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00471C70(C)
|
:00471CAA 6A10 push 00000010
* Possible StringData Ref from Code Obj ->"Error"
|
:00471CAC B9281D4700 mov ecx, 00471D28
* Possible StringData Ref from Code Obj ->"Sorry, this registration code "
->"is invalid!"
|
:00471CB1 BA301D4700 mov edx, 00471D30
:00471CB6 A1C0404700 mov eax, dword ptr [004740C0]
:00471CBB 8B00 mov eax, dword ptr [eax]
:00471CBD E84250FDFF call 00446D04
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00471CA8(U)
|
:00471CC2 33C0 xor eax, eax
:00471CC4 5A pop edx
:00471CC5 59 pop ecx
:00471CC6 59 pop ecx
:00471CC7 648910 mov dword ptr fs:[eax], edx
As you can see, the routine containing the serial check is probably located
at :0046CCB0... So let's take a look over there ;-)
:0046CCB0 55 push ebp
:0046CCB1 8BEC mov ebp, esp
:0046CCB3 51 push ecx
:0046CCB4 53 push ebx
:0046CCB5 56 push esi
:0046CCB6 8955FC mov dword ptr [ebp-04], edx
:0046CCB9 8BF0 mov esi, eax
:0046CCBB 8B45FC mov eax, dword ptr [ebp-04]
:0046CCBE E81171F9FF call 00403DD4
:0046CCC3 33C0 xor eax, eax
:0046CCC5 55 push ebp
:0046CCC6 68A4CD4600 push 0046CDA4
:0046CCCB 64FF30 push dword ptr fs:[eax]
:0046CCCE 648920 mov dword ptr fs:[eax], esp
:0046CCD1 33DB xor ebx, ebx
:0046CCD3 C605B858470000 mov byte ptr [004758B8], 00
:0046CCDA B8BC584700 mov eax, 004758BC
:0046CCDF E8C06CF9FF call 004039A4
:0046CCE4 8B45FC mov eax, dword ptr [ebp-04]
:0046CCE7 E8346FF9FF call 00403C20
:0046CCEC 83F80C cmp eax, 0000000C
:0046CCEF 0F8599000000 jne 0046CD8E
:0046CCF5 8B45FC mov eax, dword ptr [ebp-04]
:0046CCF8 803838 cmp byte ptr [eax], 38
:0046CCFB 0F858D000000 jne 0046CD8E
:0046CD01 8B45FC mov eax, dword ptr [ebp-04]
:0046CD04 80780233 cmp byte ptr [eax+02], 33
:0046CD08 0F8580000000 jne 0046CD8E
:0046CD0E 8B45FC mov eax, dword ptr [ebp-04]
:0046CD11 80780331 cmp byte ptr [eax+03], 31
:0046CD15 7577 jne 0046CD8E
:0046CD17 8B45FC mov eax, dword ptr [ebp-04]
:0046CD1A 80780439 cmp byte ptr [eax+04], 39
:0046CD1E 756E jne 0046CD8E
:0046CD20 8B45FC mov eax, dword ptr [ebp-04]
:0046CD23 80780830 cmp byte ptr [eax+08], 30
:0046CD27 7565 jne 0046CD8E
:0046CD29 8B45FC mov eax, dword ptr [ebp-04]
:0046CD2C 80780935 cmp byte ptr [eax+09], 35
:0046CD30 755C jne 0046CD8E
:0046CD32 8B45FC mov eax, dword ptr [ebp-04]
:0046CD35 80780A53 cmp byte ptr [eax+0A], 53
:0046CD39 7553 jne 0046CD8E
:0046CD3B 8B45FC mov eax, dword ptr [ebp-04]
:0046CD3E 80780B45 cmp byte ptr [eax+0B], 45
:0046CD42 754A jne 0046CD8E
:0046CD44 B8BC584700 mov eax, 004758BC
:0046CD49 8B55FC mov edx, dword ptr [ebp-04]
:0046CD4C E8A76CF9FF call 004039F8
:0046CD51 C605B858470001 mov byte ptr [004758B8], 01
:0046CD58 B301 mov bl, 01
:0046CD5A 33D2 xor edx, edx
:0046CD5C 8B8600050000 mov eax, dword ptr [esi+00000500]
:0046CD62 E86DCEFCFF call 00439BD4
:0046CD67 33D2 xor edx, edx
:0046CD69 8B8614050000 mov eax, dword ptr [esi+00000514]
:0046CD6F E8B8D9FBFF call 0042A72C
:0046CD74 33D2 xor edx, edx
:0046CD76 8B8610030000 mov eax, dword ptr [esi+00000310]
:0046CD7C E853CEFCFF call 00439BD4
:0046CD81 33D2 xor edx, edx
:0046CD83 8B860C030000 mov eax, dword ptr [esi+0000030C]
:0046CD89 E846CEFCFF call 00439BD4
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0046CCEF(C), :0046CCFB(C), :0046CD08(C), :0046CD15(C), :0046CD1E(C)
|:0046CD27(C), :0046CD30(C), :0046CD39(C), :0046CD42(C)
|
:0046CD8E 33C0 xor eax, eax
:0046CD90 5A pop edx
:0046CD91 59 pop ecx
:0046CD92 59 pop ecx
:0046CD93 648910 mov dword ptr fs:[eax], edx
:0046CD96 68ABCD4600 push 0046CDAB
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0046CDA9(U)
|
:0046CD9B 8D45FC lea eax, dword ptr [ebp-04]
:0046CD9E E8016CF9FF call 004039A4
:0046CDA3 C3 ret
A lot of jumps to 0046CD8E eh? Prolly not a nice place to jump to eh ;-)
And what do you think about all those cmp byte ptr [eax + X], XX eh?
Prrrretty suspicious if you ask me... What could that cmp eax, 0000000C
mean ? A length check ? Well I'm usually a very lazy person, so this is
what I did... I just wrote down the decimal numbers and the letters
corresponding to the ascii numbers behind all the eax compares... So:
cmp byte ptr [eax], 38 -> 8
cmp byte ptr [eax+02], 33 -> 3
cmp byte ptr [eax+03], 31 -> 1
cmp byte ptr [eax+04], 39 -> 9
cmp byte ptr [eax+08], 30 -> 0
cmp byte ptr [eax+09], 35 -> 5
cmp byte ptr [eax+0A], 53 -> S
cmp byte ptr [eax+0B], 45 -> E
Eh, but what about the spaces the program doesn't check, like [eax+01] ?
Well, it could be the program checks them later in another routine, but like
I said, I'm lazy, so for now, put some nice X's in the empty spaces...
This is what we'll get:
8X319XXX05SE
Okiz, let's enter this number in the "enter registration code"-textfield...
And.. Bingo! It works ;-)
Well that's all folks..
Greets go out to: all dread members, all faith members, all revolution members
and
all ecolove members, yosh, carpathia, bjanes, hutch, sortof, josephCo and prolly
some other dudes I forgot ;-)