FOR THE +HCU: ACADEMY OF REVERSE ENGINEERING
Win32 Code Reversing
Program Name:PowerZip v5.01
Program Type: Compression Utile
Program Location: [ here ]
Program Size: 2+MB
Published by +Tsehp Oct 2001
W32Dasm - Win'95/98 Dissasembler
Softice V4.X - DeBugger
||"It's Up to you now Young Cracker"|
Cracking A Compression
('Most Stupid Protection')
Written by Bengaly
PowerZip is a complete file compression solution for Windows. Supporting a large number of compressed formats, PowerZip enables you to compress and extract files quickly and easily. PowerZip combines a simple and easy to use user interface with great flexibility and advanced features so whether you are a novice or a power user, PowerZip is the right software to use.
|About this protection|
This program is registered by selecting the 'Help' button, 'About' button And than Registration# Button.
Number Of Copies Bought:
On Successful Registration, PowerZip will make a 'PowerZip.reg' file in it's Dir. with this information:
RegNum=-715191246 (Notice this number is diff from the real one, cuz it's transformed, notice in winice )
if you want to use this software please Buy it, This program is very good, please support it!
Hello and welcome to my 32'th Tutorial.
Again, with no internet I had to dig inside my RCE CD , and lucky me
I found this app in a
German magazine web page ripped in the cd :-) , it was some sort of a project needed to,
Be cracked, so I took it , at least something than nothing :-)
This Application does not use any special Protection, only but the regular win Protection:
Never changed doeasn't it ? :-)
Of course cracking it wont be any trouble at all, even serial fishing will be too much easy,
Although I can say the Algo is very nice (little tricky and very very annoying), also coded in VC++,
Too much junk, when ppl will learn that ASM is the best ? ohh yeah blame m$ :-( .
Any way, let's start the cracking mission
Load up PowerZip, go to the registration Dialog, enter some information :
Copies: 1 (this Bastard is kind tricky to make keygen, you'll see why ;-)
Registration Number: 12121212 (Good old teacher :-)
Press the OK Button and should get a Messagebox saying : "The
registration number is invalid."
Hmm, no Problem, let's Disassemble the PowerZip...
Take nearly a 10 seconds to disassemble this file (200k), anyway Open up the String-Ref and search
For the string,....hm...Where is it?...hm... :-/
Seems PowerZip does not use the string...that's weird (it could happen) but can't be
In our case..hm...I know what we need...alittle ZEN :-) yeah, this will probably help when you're stuck,
Ok but first put some Axel-Rudi-pell CD (Great German heavy rock guitar player, even Talisman will do)
But don't put Really heavy screaming metal ugly music, that's not ZEN that's Headeck :-)
Anyway back to our proggy, since we know that the string is not in the app's EXE, we must seek something
Else, hm...think, it's a Compression program, and also 200kbytes for the EXE, that's weird,
Also this program uses allot of compression's (CAB,ZIP,HA,ARJ,Self ZIP eXTRACTION...),
I must tell that 200k program can't handle such amount of work :-)
So there must be some Help Files, a DLLS yeah that's must be, That's why we couldn't find the
String, PowerZip.exe is just an Dialog with Imported/Exported functions from outside DLLs.
Ok, let's make the DLLs visible, on Win98 :-( View->Forlder Options->View->Show all files
Now you should see 9 different DLLS, just as i mentioned each dll correspond to his function.
Now, how can we know which DLLs is the one we need?
No problem, first look at the Dll's names, all uses the Libs (zip,ace,rar,zsfx...) but on 1 has a weird name,
More to say, Look at his Files Size 492 kbytes :-) and our PowerZip.exe is only 204kbytes, so we
Used alittle brain (not much, but we did) to find the suspicious file,
Now Lets disassemble it, and viola we have String-Ref, and more, scroll down and you will see:
"Tar Archives (*.Tar)|*.Tar|"
"Thank you for registering PowerZip!"
"The registration number is invalid."
Ahah you say, i did it, i beat the night :-) , Still there more to be
Double click on The registration number is invalid and you will be here:
|* Reference To: MFC42.Ordinal:0217, Ord:0217h
:150228C0 E8950B0100 Call 1503345A
* Reference To: DTUtil.?DT_IsValidRegNo@@YGHVCString@@II@Z
:150228C5 E8661DFFFF call 15014630 - Algo :-)
:150228CA 85C0 test eax, eax
:150228CC 7512 jne 150228E0
:150228CE 50 push eax
:150228CF 6A10 push 00000010
* Possible StringData Ref from Data Obj ->"The
registration number is invalid."
Can you believe it ?
I think it's the Most stupid protection ever, look: :-)
Yeah this is Stupid, also I can tell you, that this program made in VC++,
And so it calls IsValidRegNo() function that you see above :-) none to say, it's Stupid
Stupid Protection, but weird Algo :-) .
Ok, from what I see, Patch on the JNE wont work,
it will only show the Good message but wont
Make it registered, this is because it save a reg file, and read it from it, so of you will patch it
It fill it with fake stuff, but still when it will read it, it wont accept it.
So we need to enter the call at 15014630this where we are interested in, follow the call and we are here:
|* Referenced by a CALL at Addresses:
|:150148FC , :150228C5 ;We called from those.
Exported fn(): ?DT_IsValidRegNo@@YGHVCString@@II@Z
* Possible Reference to Dialog: DialogID_3A9E,
* Reference To: MSVCRT._itoa, Ord:0134h
;ahh VC++ :-) Convert Integer To String
* Reference To: zlib.adler32, Ord:0001h
Argh, it's long, Damm Vc++ code makes everything UnClear an messy :-(
Any way We can understand what's going on there by Debugging, But i already did,
In the Program there are 2 part of the Algo:
1. For the Number Of copies.
2. For the name + table.
Let see what's going on in Part 1 of the algo
0177:7800294D PUSH EBP
0177:7800294E MOV EBP,ESP
0177:78002950 CMP DWORD PTR [EBP+10],0A ; over 10 ?
0177:78002954 JNZ 78002960
0177:78002956 CMP DWORD PTR [EBP+08],00 ; no copies ?
0177:7800295A JL 7801327A
0177:78002960 PUSH 00
0177:78002962 PUSH DWORD PTR [EBP+10] ; Point to number 5
0177:78002965 PUSH DWORD PTR [EBP+0C] ; ?? (Sice shows: 75D5ACh)
0177:78002968 PUSH DWORD PTR [EBP+08] ; Number of copies we bought
0177:7800296B CALL 78002978 <-----------+
0177:78002970 MOV EAX,[EBP+0C] |
0177:78002973 ADD ESP,10 |
0177:78002976 POP EBP |
0177:78002977 RET |
0177:78002978 PUSH EBP <------------+
0177:78002979 MOV EBP,ESP
0177:7800297B CMP DWORD PTR [EBP+14],00 ; ?? compare some with 0, uselss from my point
0177:7800297F MOV ECX,[EBP+0C] ; ECX = 75D5AC (mabye number of copies as well)
0177:78002982 PUSH EBX ; stack save
0177:78002983 PUSH ESI ; stack save
0177:78002984 PUSH EDI ; stack save
0177:78002985 JNZ 78013283 ; Jump not equal to stack save esi ;-/ (junk?)
0177:7800298B MOV ESI,[EBP+08] ; ESI = 1 (we choose 1 copy remember?)
0177:7800298E MOV EDI,ECX ; EDI = 75D5AC (pointer to 1?)
0177:78002990 MOV EAX,ESI ; EAX = 1
0177:78002992 XOR EDX,EDX ; EDX = 0
0177:78002994 DIV DWORD PTR [EBP+10] ; Devide by 5
0177:78002997 MOV EAX,ESI ; EAX = ESI
0177:78002999 MOV EBX,EDX ; EBX = 1 (EDX does not affect ebx, junk C++)
0177:7800299B XOR EDX,EDX ; Xor again :-/ (VC++ junk :-)
0177:7800299D DIV DWORD PTR [EBP+10] ; Devide by 5 (VC++ junk :-)
0177:780029A0 CMP EBX,09 ; EBX=9? (this may cuz after 9(copies) it does diff calcs)
0177:780029A3 MOV ESI,EAX ; ESI = 0
0177:780029A5 JA 78013291 ; If there were more than 9 copies ? (i think so)
0177:780029AB ADD BL,30 ; EBX = 1 + 30 = 31 ('1')
0177:780029AE MOV [ECX],BL ; Move it to the adress of ECX
0177:780029B0 INC ECX ; ECX increased (address) -> 75D5AD
0177:780029B1 TEST ESI,ESI ; Is There remaining calculations ?
0177:780029B3 JA 78002990 ; Yup we haven't finished yet, jump
0177:780029B5 AND BYTE PTR [ECX],00 ; AND address with 00 (More junk)
0177:780029B8 DEC ECX ; ECX goes down to 75D5AC
0177:780029B9 MOV DL,[EDI] ; EDX = 31 ('1') (DL=30)
0177:780029BB MOV AL,[ECX] ; EAX = 31 ('1') (AL = 30)
0177:780029BD MOV [ECX],DL ; save (more junk ahead)
0177:780029BF MOV [EDI],AL ; save (yeah kill CPU time)
0177:780029C1 DEC ECX ; ECX = 75D5AB
0177:780029C2 INC EDI ; EDI = 75D5AC
0177:780029C3 CMP EDI,ECX ; Make Comparison (ECX = 1's magic number, write it)
0177:780029C5 JB 780029B9 ; below? than jump to junk
0177:780029C7 POP EDI ; original stack
0177:780029C8 POP ESI ; origianl..
0177:780029C9 POP EBX ; original...
0177:780029CA POP EBP ; original...
0177:780029CB RET ; Finished abuse you CPU, exit :-)
What can I say, Total mess, this is what happened when you code in VC++
Any way, let me originize some Air to breeth and tell you what's going on, it is very weird
Becasue it's is coded in C and there is too much junk, explanation:
1. takes the number of copies you shoose in HEX (i choosed 1)
2. divide it with magic num 5 (EAX = 1/5 = 0, without reminder)
3. check to see if there is more number to divide in eax
4. add 30h to the number we entered (1h+30h => 31h =>'1')
5. save it for the second part of the algo.
But this is easy as it's 1 number, try to put big num and you get Headeck,
I choosed 400 copies :-), it's more than 9 so:
190h / 5h = 50h
50h / 5h = 10h
10h / 5h = 3h
3h / 5h = 0
And than do something weird here with adding 30h and if esi below ecx, it will keep
Move in 30h very weird.
from the above example the magic number is 100Dec ( and it's not a sum)
*Hope someone can give me a hint on that ? :-) plz contact me.
anyway i got magic number 1 from this weird calculation for the number
of copies 1, dont worry
It does give other numbers :-) , well this goes for the First part,
Second part Of algo:
There is no actually code for this second part, but only created in
I will Explain the main idea of how to make a valid serial:
Magic Number + Name (uppercase) + table
All those togethere with some code makes a valid number, now you can't find it in win32dasm ro so,
so you need to rip it from softICE, here is an example to my valid serial from my name:
|Here ot does the same as below only start from
the first char of the built table
0177:026810D3 MOV DL,[ESI-02] ; move char
0177:026810D6 ADD EDI,ECX ; char + ecx
0177:026810D8 ADD ECX,EDX ; ecx + edx
0177:026810DA XOR EDX,EDX ; make room for another char
0177:026810DC MOV DL,[ESI-01] ;last char
0177:026810DF ADD EDI,ECX ;....
0177:026810E1 ADD ECX,EDX ;...
0177:026810E3 ADD EDI,ECX ;...
0177:026810E5 DEC EBP
0177:026810E6 JNZ 02681050
0177:026810EC TEST EAX,EAX
0177:026810EE JZ 026810FC
0177:026810F0 XOR EDX,EDX
0177:026810F2 MOV DL,[ESI]
0177:026810F4 ADD ECX,EDX
0177:026810F6 INC ESI
0177:026810F7 ADD EDI,ECX
0177:026810F9 DEC EAX
0177:026810FA JNZ 026810F0
0177:026810FC MOV EAX,ECX
0177:026810FE XOR EDX,EDX
0177:02681100 MOV ECX,0000FFF1
0177:02681105 DIV ECX
0177:02681107 MOV EAX,EDI
0177:02681109 MOV EDI,0000FFF1
0177:0268110E MOV ECX,EDX
0177:02681110 XOR EDX,EDX
0177:02681112 DIV EDI
0177:02681114 TEST EBX,EBX
0177:02681116 MOV EDI,EDX
0177:02681118 JA 02681031
0177:0268111E POP EBP
0177:0268111F MOV EAX,EDI
0177:02681121 POP EBX
0177:02681122 SHL EAX,10
0177:02681125 POP EDI
0177:02681126 OR EAX,ECX ; Built Serial Here
0177:02681128 POP ESI
0177:02681129 RET 000C
It's not hard to to understand this piece of code, it builds up a Table
Mine was: 1BENGALYPowerZip
Here's how Everythings Work:
1 . Calculated magic number from the first algo. (copies related)
2. Convert name to uppercase (Bengaly -> BENGALY)
3. add the string table 'PowerZip 5, Standard Edition' before the second algo
4. get lenght = 36 dec
5. cut down the 5, Standard Edition String.
6. get every char from table (1BENGALYPowerZip) and sum the values
7. alittle more calculations here :-)
8. eax OR ecx Builds the final serial
For me I got :
If you wish to built an keygen, it's posible as long as you figure out
the part 1 of the algo,
Please send me solution for part 1 algo :-) as i was too lazy to understznd it.
Work Well and cya Next time.
Do I really have to remind you all that by buying and NOT stealing the software you use will ensure that these software houses will continue to produce even *better* software for us to use and more importantly, to continue offering even more challenges to breaking their often weak protection systems.
If your looking for cracks or serial
numbers then your wasting your time, try searching elsewhere on the Web
under Warez, Cracks and etc.
I would like to say thank you to all who has supported me, and helped me through my cracking days:
First Thanks goes to all who made Reveres-Engineering Possible:
In no specific order:
|+ORC, reverser+, +RGC, +greythorne, +ReZiDeNt,
+Xoanon , SiuL+Hacky,
The+Q (Home Made), +Spath, +Mammon_, Frog's print, +gthorne, +daQ,
razzia, +MaLaTTiA, Quine, +Alt-F4, +DataPimp, The+Chineese, +Hackmore,
+Indian_Trail, bajunny, +Sandman, +Aesculapius, Shaman, +Aitor,
Dr Fuhrball, MaD, TWD, +SNikKkEL, +Sync, Flipper, +Spalj, +Tsehp,
A+heist, The Undertaker, Civetta, +Zer0, +drlan, +PopJack.
|all the HCUkers out there, we'll never forget you,
And to those who has past away from this world we'll remember you as well.
Thank for my Cracking Skills (Whatever they are) Goes To
|CoDe_InSiDe, fusS, _Nordic_, Muad'D1b, gogamoga,
ManKind, PGC & +HCU Academy Support.
And Thanx to my real friends as well (even if some don't know what I do) :-)
Work Well And Have Fun.