Cracking Tutorial
#72:
Picture Agent V2.7c2
[cracked bY:] sLeEpY¿[FWA/NWA/FTPR8Z] iN 08/2002
[difficulty:] beginner/intermediate
[where:] http://www.pictureagent.com/
[tOOLz:] W32dasm 8.93, Hiew, Softice 4.05, Regmon
KANAL23 Tutorial
Picture Agent V2.7c2 |
|
---|---|
Download it from |
Written by |
sLeEpY¿ |
---|
Tools |
|
---|
Rating |
|
---|
Introduction |
---|
Yo...
Well i was checking out fravia's site and read her mention something in this
program having blacklisted usernames, so out of curiosity we will disassemble
this program and check that out, also we will crack this prog, then we will find
out how to get a valid serial from our entered username using softice. Also this
is a long tutorial so jam some tunes, like a playlist of crap.
The Essay |
---|
Picture Agent V2.7c2
HERE WE GO!
First disassemble the prog and make the usual backups. Run it and we get a nag
and another nag, then we have the app and you can see in the title bar:
(*UNREGISTERED*) -
Run it again and try to register it and we get the crappy error message. Lets
make this thing take any name and code, Look in the String Refs for what you
think would be the happy message:
:004151B8 7448 je 00415202
<-hmm... conditional
jump
:004151BA 6A00 push 00000000
:004151BC 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"Registration information accepted"
So we just need to change this:
:004151B8 7448 je 00415202
To this:
:004151B8 9090 Nopx2
Now any name/code combo will reg the program but it wont stick and doesn't even
stay in the title bar. So next lets get rid of that unsightly "unregistered" in
the title bar...
Check out the dead list in the string refs for that, double click it and here we
are:
* Possible StringData Ref from
Data Obj ->"PictureAgent "
:0040C222 68481D4200 push 00421D48
:0040C227 0F84A7000000 je 0040C2D4
<-Nop this or reverse it,
below is where it craps
:0040C22D 8D442420 lea eax, dword ptr [esp+20]
:0040C231 50 push eax
* Reference To: MFC42.Ordinal:039E, Ord:039Eh
:0040C232 E8C1A80000 Call 00416AF8
* Possible StringData Ref from Data Obj ->" (Registered to: "
If you take the above jump it lands here:
* Referenced by a (U)nconditional
or (C)onditional Jump at Address:
|:0040C227(C)
|
:0040C2D4 8D44241C lea eax, dword ptr [esp+1C]
:0040C2D8 50 push eax
* Reference To: MFC42.Ordinal:039E, Ord:039Eh
:0040C2D9 E81AA80000 Call 00416AF8
* Possible StringData Ref from
Data Obj ->" (*UNREGISTERED*) -"
<-bad crap out
So change this:
:0040C227 0F84A7000000 je
0040C2D4
To this:
:0040C227 909090909090 NOPX6
And now when we register our name will appear at the top of the app, unless of
course you used one of the following names...check it out below, hard coded
blacklisted usernames.
Black listed names! Look at all these bad bad
people =)
Start here:
* Reference To: MSVCRT._mbscmp,
Ord:0154h
:00415388 8B35B43B4200 mov esi, dword ptr [00423BB4]
* Possible StringData Ref from Data Obj ->"paid copy"
:0041538E 683C274200 push 0042273C
:00415393 51 push ecx
:00415394 FFD6 call esi
:00415396 83C408 add esp, 00000008
:00415399 F7D8 neg eax
:0041539B 1BC0 sbb eax, eax
:0041539D 40 inc eax
:0041539E 84C0 test al, al
:004153A0 0F8511060000 jne 004159B7
<-is this the user above? if
so jump to crap out
:004153A6 8B542410 mov edx, dword ptr [esp+10]
* Possible StringData Ref from Data Obj ->"bit byter"
<-all these names are
* Possible StringData Ref from Data Obj ->"tracy"
<-blacklisted and have the
same
* Possible StringData Ref from Data Obj ->"g-rom"
<-basic jne to reverse or nop
* Possible StringData Ref from Data Obj ->"serial online!"
<-to use the name
* Possible StringData Ref from Data Obj ->"windows 95"
<-again...fix the jne.
* Possible StringData Ref from Data Obj ->"free copy"
* Possible StringData Ref from Data Obj ->"free loader"
* Possible StringData Ref from Data Obj ->"bates"
* Possible StringData Ref from Data Obj ->"nobody!"
* Possible StringData Ref from Data Obj ->"bob dole"
* Possible StringData Ref from Data Obj ->"cheep ass"
* Possible StringData Ref from Data Obj ->"agent 2000"
* Possible StringData Ref from Data Obj ->"3000gt"
* Possible StringData Ref from Data Obj ->"microsoft corp"
* Possible StringData Ref from Data Obj ->"free stuff"
* Possible StringData Ref from Data Obj ->"picture agent"
* Possible StringData Ref from Data Obj ->"iceman [ucf]"
<-hey a ucf member
* Possible StringData Ref from Data Obj ->"hans die wurst"
* Possible StringData Ref from Data Obj ->"escom/core"
<-hey a core member
* Possible StringData Ref from Data Obj ->"jennifer miller"
* Possible StringData Ref from Data Obj ->"burkhard weuste"
* Possible StringData Ref from Data Obj ->"junko suzuk"
* Possible StringData Ref from Data Obj ->"george mehler"
* Possible StringData Ref from Data Obj ->"janice schomaker"
* Possible StringData Ref from Data Obj ->"eric fitch"
* Possible StringData Ref from Data Obj ->"leroy gillett"
* Possible StringData Ref from Data Obj ->"jack anderson"
* Possible StringData Ref from Data Obj ->"michael nazari"
* Possible StringData Ref from Data Obj ->"mike hawk"
* Possible StringData Ref from Data Obj ->"m goodge"
* Possible StringData Ref from Data Obj ->"pai su yin"
* Possible StringData Ref from Data Obj ->"karen hammond"
* Possible StringData Ref from Data Obj ->"gene mayer"
* Possible StringData Ref from Data Obj ->"dorothy gray"
* Possible StringData Ref from Data Obj ->"khon cam trinh"
* Possible StringData Ref from Data Obj ->"thomas lamb"
* Possible StringData Ref from Data Obj ->"mark sethre"
* Possible StringData Ref from Data Obj ->"jesica bedford"
* Possible StringData Ref from Data Obj ->"wallace gorrell"
* Possible StringData Ref from Data Obj ->"timothy sullivan"
* Possible StringData Ref from Data Obj ->"enrique sesman"
* Possible StringData Ref from Data Obj ->"daniel brisebois"
* Possible StringData Ref from Data Obj ->"henry tyler"
* Possible StringData Ref from Data Obj ->"arnold lander"
* Possible StringData Ref from Data Obj ->"thomas hanley"
* Possible StringData Ref from Data Obj ->"guanming wang"
* Possible StringData Ref from Data Obj ->"jiantong yu"
* Possible StringData Ref from Data Obj ->"donald ibarra"
* Possible StringData Ref from Data Obj ->"keith graves"
* Possible StringData Ref from Data Obj ->"hacker"
If you use one of these names and don't change or nop the jne after it, and you
already cracked the "registered to" part, well the name wont show up hehe, but
put in a name that isn't on the list and you will be regged ok. Nothing like
Hard coded blacklisting, must have had a lot of people pirate there software.
Well now we have the nag screen to crack away.
So we know the title of the nag screen is "Register PictureAgent" so lets search
for it in w32dasm just using a general search of the dead list. You will see it
popup here:
Register PictureAgent
<-title bar of nag screen #1
Name: DialogID_008F, # of Controls=009, Caption:"Register PictureAgent",
ClassName:""
OK so now we have the dialog ID, check out the Dialog Refs and couble click on
DialogID_008F and you should land in this code.
* Referenced by a CALL at
Address:
|:0040C050 <-well we
now know that this is where the dialog is called from
|
:00415040 6AFF push FFFFFFFF
:00415042 68239F4100 push 00419F23
:00415047 64A100000000 mov eax, dword ptr fs:[00000000]
:0041504D 50 push eax
:0041504E 64892500000000 mov dword ptr fs:[00000000], esp
:00415055 51 push ecx
:00415056 8B442414 mov eax, dword ptr [esp+14]
:0041505A 56 push esi
:0041505B 57 push edi
:0041505C 8BF1 mov esi, ecx
:0041505E 50 push eax
* Possible Reference to Dialog: DialogID_008F
:0041505F 688F000000 push 0000008F
<-start here!!!!!!!!
:00415064 89742410 mov dword ptr [esp+10], esi
* Possible Ref to Menu:
MenuID_0069, Item: "Ok"
:0040C03B C7467C01000000 mov [esi+7C], 00000001
:0040C042 E859050000 call 0040C5A0
:0040C047 85C0 test eax, eax
:0040C049 7566 jne 0040C0B1
<-conditional jump
:0040C04B 53 push ebx
:0040C04C 8D4C2458 lea ecx, dword ptr [esp+58]
:0040C050 E8EB8F0000 call 00415040
<-call nag screen
Please register your copy of picture agent
<-nag screen #2, taken out
with nag one =)
So to get rid of the nag just change this:
:0040C049 7566 jne 0040C0B1
To this:
:0040C049 EB66 jmp 0040C0B1
Where is our user info stored?
Using regmon we see that our registry information is stored here:
C:\WINDOWS\PICTUREAGENT.INI
open it up and you will find this:
[PictureAgent]
Name=sleepy (or whatever name you put in)
Registration=666 (or whatever serial you put in)
So to make a crack we just patch all the places above and make this file and
stick in C:\windows and every time the program is run it will show the name
here!
Now the fun part of this tutorial. A lot of
people can sniff a serial number with Softice but learning how it comes up with
the serial is a bit more work but it is also interesting and great to learn
from!
In Softice we can set a breakpoint on "hmemcpy" and
try to validate our username and regcode (using an unpatched copy) and
F10 a ton of times till we get to this code
routine. The routine starts here: 415929 where it
puts the first char of your name in BL, then ends
here at : 415967, where it loops to the next char
of your name. Here I will explain how the routine works and if you can't follow
read some of my other tuts and learn basic softice.
The information below will probably be all you need to make a keygen.
* Referenced by a (U)nconditional
or (C)onditional Jump at Address:
|:00415967(C)
|
:00415929 8A1C06 mov bl, byte ptr [esi+eax]
<-bl holds current char value
of username, one at a time
:0041592C 8BCD mov ecx, ebp
:0041592E 8D7E01 lea edi, dword ptr [esi+01]
:00415931 E80A010000 call 00415A40
<-see call 1 below
:00415936 8BD0 mov edx, eax
:00415938 8BCD mov ecx, ebp
:0041593A 2BD6 sub edx, esi
:0041593C 89542418 mov dword ptr [esp+18], edx
:00415940 E8EB000000 call 00415A30
<-see call 2 below
:00415945 8B542418 mov edx, dword ptr [esp+18]
:00415949 8B742414 mov esi, dword ptr [esp+14]
:0041594D 0FBECB movsx ecx, bl
:00415950 2BC1 sub eax, ecx
:00415952 0FAFD0 imul edx, eax
:00415955 0FAFD7 imul edx, edi
:00415958 8B44242C mov eax, dword ptr [esp+2C]
:0041595C 03F2 add esi, edx
:0041595E 89742414 mov dword ptr [esp+14], esi
:00415962 8BF7 mov esi, edi
:00415964 3B70F8 cmp esi, dword ptr [eax-08]
:00415967 7CC0 jl 00415929
<-loop until all chars from
username are gone
:00415969 8B7C2414 mov edi, dword ptr [esp+14]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00415927(C)
|
:0041596D 8B442430 mov eax, dword ptr [esp+30]
:00415971 3BF8 cmp edi, eax
<-edi holds valid serial, eax
hold entered serial
:00415973 757A jne 004159EF
<-bad craphole jump
Compare is here: :00415971
3BF8 cmp edi, eax
? EDI = 2298801 <-valid serial
? EAX = 98765 <-fakey
User: sleepy
Serial: 2298801
CALL 1
* Referenced by a CALL at
Address:
|:00415931
|
:00415A40 B877000000 mov eax, 00000077
<-put 77 in EAX
:00415A45 C3 ret
<-return from call
CALL 2
* Referenced by a CALL at
Address:
|:00415940
|
* Possible Reference to Dialog: DialogID_0082, CONTROL_ID:0421, "&Update"
:00415A30 B821040000 mov eax, 00000421
<-put 421 in EAX
:00415A35 C3 ret
<-return from call
Well now lets look at how this all works:
* Referenced by a (U)nconditional or (C)onditional Jump at
Address:
|:00415967(C)
|
:00415929 8A1C06 mov bl, byte ptr [esi+eax] <-bl
holds current char value of username, one at a time
:0041592C 8BCD mov ecx, ebp
:0041592E 8D7E01 lea edi, dword ptr [esi+01] <-edi
is the counter, = 1 on first char and counts upward
:00415931 E80A010000 call 00415A40 <-this call
loads 119d into EAX
:00415936 8BD0 mov edx, eax <-mov EAX into EDX, EDX
= 119d
:00415938 8BCD mov ecx, ebp
:0041593A 2BD6 sub edx, esi <-EDX - ESI (counter)
into EDX, 119 - 0 on first char
:0041593C 89542418 mov dword ptr [esp+18], edx
<-put EDX into ESP+18 (ESP+18 = 119d)
:00415940 E8EB000000 call 00415A30 <-this call
loads 1057d in EAX
:00415945 8B542418 mov edx, dword ptr [esp+18]
<-put esp+18 into EDX, EDX=119d
:00415949 8B742414 mov esi, dword ptr [esp+14]
<-put esp+14 in esi, ESI = 0 on first and is the counter, 1 on second pass, ect
:0041594D 0FBECB movsx ecx, bl <-put current char
value of username in ECX
:00415950 2BC1 sub eax, ecx <-subtract ECX from EAX
and put in EAX, EAX = 1057d - Char value = new EAX value
:00415952 0FAFD0 imul edx, eax <-Multiply EAX * EDX
:00415955 0FAFD7 imul edx, edi <-Multiply EDX * EDI
:00415958 8B44242C mov eax, dword ptr [esp+2C] <-Mov
esp+2C into EAX, esp+2c put name back into EAX
:0041595C 03F2 add esi, edx <-Add ESI + EDX
:0041595E 89742414 mov dword ptr [esp+14], esi
:00415962 8BF7 mov esi, edi <-counter
:00415964 3B70F8 cmp esi, dword ptr [eax-08]
:00415967 7CC0 jl 00415929 <-loop until all chars
from username are gone
:00415969 8B7C2414 mov edi, dword ptr [esp+14]
<-esp+14 has serial
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00415927(C)
|
:0041596D 8B442430 mov eax, dword ptr [esp+30]
:00415971 3BF8 cmp edi, eax <-edi holds valid
serial, eax hold entered serial
:00415973 757A jne 004159EF <-bad craphole jump
Lets look at this again with the value "s" in the username field:
mov bl, byte ptr [esi+eax]
<-bl = "s" or 115d
mov ecx, ebp
lea edi, dword ptr [esi+01]
<-edi = 1
call 00415A40 <-EAX =
115d
mov edx, eax <-EDX =
115d
mov ecx, ebp
sub edx, esi <-115d -
0d = 115d
mov dword ptr [esp+18], edx
<-EDX = 115d
call 00415A30 <-EAX =
1057d
mov edx, dword ptr [esp+18]
<-EDX=115d
mov esi, dword ptr [esp+14]
<-ESI = 0
movsx ecx, bl <-ECX =
115d
sub eax, ecx <-1057d -
115 = 942, EAX = 942
imul edx, eax <-942d *
119d = 112098d, EDX = 112098d
imul edx, edi <-112098d
* 1 = 112098d, EDX = 112098d
mov eax, dword ptr [esp+2C]
<-Mov esp+2C into EAX, esp+2c
put name back into EAX
add esi, edx <-0d +
112098d = 112098d in ESI
mov dword ptr [esp+14], esi
mov esi, edi <-counter
cmp esi, dword ptr [eax-08]
jl 00415929 <-loop
until all chars from username are gone
mov edi, dword ptr [esp+14]
<-esp+14 = 112098d, put it in
EDI
mov eax, dword ptr [esp+30]
cmp edi, eax <-edi
holds valid serial, 112098d, eax hold entered serial
jne 004159EF <-bad
craphole jump
So if we enter username as "s" the serial is "112098".
Lets add the second letter "l"...
mov bl, byte ptr [esi+eax]
<-bl = "l" or 108d
mov ecx, ebp
lea edi, dword ptr [esi+01]
<-edi = 2
call 00415A40 <-EAX =
108d
mov edx, eax <-EDX =
108d
mov ecx, ebp
sub edx, esi <-119d -
1d = 118d
mov dword ptr [esp+18], edx
<-EDX = 118d
call 00415A30 <-EAX =
1057d
mov edx, dword ptr [esp+18]
<-EDX=119d
mov esi, dword ptr [esp+14]
<-ESI = 0
movsx ecx, bl <-ECX =
115d
sub eax, ecx <-1057d -
115 = 942, EAX = 942
imul edx, eax <-942d *
119d = 112098d, EDX = 112098d
imul edx, edi <-112098d
* 1 = 112098d, EDX = 112098d
mov eax, dword ptr [esp+2C]
<-Mov esp+2C into EAX, esp+2c
put name back into EAX
add esi, edx <-112098d
+ 223964d = 336062d in ESI
mov dword ptr [esp+14], esi
mov esi, edi <-counter
cmp esi, dword ptr [eax-08]
jl 00415929 <-loop
until all chars from username are gone
mov edi, dword ptr [esp+14]
<-esp+14 = 336062d, put it in
EDI
mov eax, dword ptr [esp+30]
cmp edi, eax <-edi
holds valid serial, 336062d, eax hold entered serial
jne 004159EF <-bad
craphole jump
So the serial for "sl" would be "336062".
Ok now you know how it calculates the serial from your name.
Here is a formula to make it easier, just incorporate it into a language:
Where X is the decimal value of the current char of the username.
Where Y is the counter starting at 0.
1057 - X = A
119 - Y = B
A * B = C
C * D = E
E + F = Solution
In use we see this: (assuming entered char is "s")
1057 - 115 = 942
119 - 0 = 119
942 * 119 = 112098
112098 * 1 = 112098
112098 + 0 = 112098
Next we enter "l":
1057 - 108 = 949
119 - 1 = 118
949 * 118 = 111982
111982 * 2 = 223964
223964 + 112098 = 336062
Final thoughts |
---|
Allright, if you figure out a keygen send me an email of how ya did, i'm always
interested in different ways/languages to do it.
Phew, long ass tutorial, that's number 72, hope ya enjoyed it.
Laterz!
Greetings |
---|
Groups:
FWA, NWA, FTPiRatEz! HAR! BEASTFXP!, KANAL23
Individuals:
MiNioN,
GreycZ & his cuppy, KlutCh, KiNgEr, MidNight, Edogg, Neoman, movax4c00int21, Acid_Cool_178, All those tuts I read
from everyone who writes them.
CopyLeft:
sLeEpY¿
[all rights reversed]
Boredom causes crackers and babies.
Visit http://zor.org/sleepy &
http://www.bright.net/~testsubject001
Mail sleepy@linuxwaves.com
This Document is copyrighted by kanal23 and it's members. Please mail the
author of this document for complaints and those things.
Kanal23
is signing out for now.