|
|
Win32 Code Reversing |
|
|
|
|
|
|
Program Name:Grocery Companion v1.2 Program Type: Saving Money Utile Program Location: [ here ] Program Size: 652 kb
|
||
W32Dasm - Win'95/98 Dissasembler (optional) Softice V4.X - De-Bugger Resource Builder v1.0 - resource build |
||
|
|
"We Are Racing Threw Time In Order To Crack Our Goal" |
Cracking A Win32 Web
Utility
('Bad Protection, Good Sniff Out, Easy
KeyGen')
Written By Bengaly
|
Grocery Companion was designed to help you save money on your grocery purchases. The main screen is broken down into aisles, so you can see how much you spend in each section of the store. A single click lets you hide a grocery item in the grocery list and shows you the new total without the hidden grocery item. Another single click lets you attach a coupon to a grocery item. A coupon section shows you the total savings from coupons. After you've finished creating your grocery list, a printed copy is only a couple of clicks away.
In Version 1.1, an option to edit Aisle headings is added. Also, the Help file has been updated. Version 1.2 features new enhancements and expanded compatibility.Registration costs $12. The unregistered version limits you to 20 grocery items in the grocery list.
About this protection |
This program is registered by selecting the 'Help' button, then
the 'About' button.
User name:
Registration:
On successful registration the program will save your User/serial in
the registry:
HKEY_CURRENT_UDER/Software/Bshelton/Grocery/code
User: Bengaly
Name: 5379333 <--
This is Generated by the program! (It will transform the serial into HEX:
521505 in the registry)
If u want to use this software please Buy it, it's 12$ the program is very good, please support It!
|
Hello and welcome to my 29th Tutorial :=).
Today we are going to Register a small program i have found on the net!
I must say the programmers Implemented a very weak Protection into
the main code.
Instead making their program efficient they only make use practice
on those protections more and more
Since we are going to Dig the Serial I will explain the algo and where
is the Actual serial is generated.
Although there are allot of types of programs every one of them still
use this lame way: CMP ->JNZ (JNE)
Enough talking..there is no point to me to keep talk as u all know
how to crack such type of easy protection,
But still fun to read and gain knowledge.
Also i will teach you a trick: "how to find the program's code with
Hmemcpy", a very good method i found by my self, this will Eliminate the
newbies questions about F12 via Hmemcpy.
Also A keygen Explanation Include (My First KeyGen..Was Really Hard
to code..at least to me)
We load the program and go straight to the 'ABOUT'
We are welcomed by a Serial/Name input Box, now fill in the info u
wish to.
Name: Bengaly
Serial: 12121212 [ Gotta love +ORC ;=) ]
Press OK button, u will greet with a Bad_Boy messageBox saying we entered
a bad serial number for our name.
Hm..not too hard, but since API calls are not working with this program
[GetWindowTextA,GetDlgItemTextA] for instance
We will use the System Function: HmemCPY [Memory Copy function].
So load WinICE and set the BPX on HmemCPY <enter>
Press either: 'X' / 'F5' / 'Ctrl-D' to exit.
Now that WinICE is waiting to the next Memory copy we press the OK
Button.
Note that the first break is nothing to do with our Program's Code...we
are just in a DLL .
We will continue..Press F5 to read the Serial Edit Box WinICE will
Drop us here:
-----------KERNEL!LOGERROR+0123-----------------------------------------------------------------PROT16
0157:9EA3 RETF 0008 KERNEL!HMEMCPY 0157:9EA6 PUSH BP 0157:9EA7 MOV BP,SP 0157:9EA9 PUSH DS 0157:9EAA PUSH EDI 0157:9EAC PUSH ESI 0157:9EAE CLD 0157:9EAF MOV ECX,[BP+06] 0157:9EB3 JECXZ 9F2D ------------------------------------------------------------------------KERNEL(01)---------------------------------------- |
Hm..still nothing to do with the program's code [check routine]..keep
pressing F12 from now on.
So keep pressing until You see this:
0177:0041FB72 CALL
00420360
0177:0041FB77 RET <= The Magical Ret 0177:0041FB78 MOV [EAX+5C],EDX 0177:0041FB7B TEST EDX,EDX 0177:0041FB7D JZ 0041FB85 0177:0041FB7F XCHG EAX,EDX 0177:0041FB80 CALL 00412978 0177:0041FB85 RET 0177:0041FB86 MOV EAX,EAX 0177:0041FB88 PUSH EBX |
Note that: no metter how many times u pressed F12 if there is
no API called from the program so this Method is 100% Working.
Everyone should see this in his WinICE ...that's why this method is
100% working.
This method will Eliminate the lame Questions like:
1. "how do you know how many times you need
to press F12 to get to the actual code?"
2. "how can i find the program code with Hmemcpy?"
Now that we landed on the RET command we are 1
step away from the Program's Code Check Routine!
Press F12 1 time and you are inside the Check
Routine.
WinICE shows us this:
0177:0046A0C0 CALL
0041FBAC ;
Read Input
0177:0046A0C5 MOV EAX,[EBP-04] ; EAX = Fake Serial 0177:0046A0C8 XOR EDX,EDX ; EDX = 0 (Reset EDX) 0177:0046A0CA CALL 004072B4 ; EAX='12121212' ,D ECX = '12121212' 0177:0046A0CF MOV EDX,[0048AE08] ; 0048AE08 = Memory location of my fake serial 0177:0046A0D5 MOV [EDX],EAX ; D *EDX = '12121212' 0177:0046A0D7 MOV EDX,[0048AD60] ; 0048AD60 = Our Name: 'Bengaly' 0177:0046A0DD MOV EDX,[EDX] ; EDX= Our Name 0177:0046A0DF LEA EAX,[EBP-08] ; Not Important 0177:0046A0E2 MOV ECX,0046A158 ;ECX = 0046A158 = 'Bad Message' 0177:0046A0E7 CALL 00403C1C ; EAX = Fh (15 Dec) ?? 0177:0046A0EC MOV EAX,[EBP-08] ; EAX = 'Bengaly' 0177:0046A0EF CALL 00469980 ; Algo!!!! 0177:0046A0F4 MOV EDX,[0048AE08] ; EDX = 0048AE08 0177:0046A0FA CMP EAX,[EDX] ; ? EAX='5379333' / ? EDX = '12121212' 0177:0046A0FC MOV EAX,[0048ADE4] ; Not Important 0177:0046A101 SETZ BYTE PTR [EAX] ; Possible Patch: SETZ->SETNZ 0177:0046A104 MOV EAX,[0048ADE4] ; Not Important 0177:0046A109 CMP BYTE PTR [EAX],00 ; Flag-City: CMP BYTE PTR [EAX],01 - PATCH 0177:0046A10C JNZ 0046A123 ; Jump Not Equale 0177:0046A10E PUSH 0A ; save Window Handle ? |
Now that won't be hard to understand, will it?
The CMP Opcode will Compare EAX and Memory location of [EDX]
D EAX at 0046A0FA Wont show Us anything in WinICE..so
therefore Try ? EAX
And We get the number : 5379333
(Dec)
D [EDX] at 0046A0FA Wont show Us anything as
well In WinICE..so therefore ? *[EDX] will Dump
Us what [EDX] is, in our case the Fake serial:
12121212
Note: ? *[EDX] , * is to dump the memory location,
if we had done ? [EDX] we wouldn't get 12121212 cuz
We must dump the actuall memory location by
adding *.
Job Done.
|
Now that we know where the real serial is compared
with the fake serial, a good look up in the algo will make us
Understand how The serial is being Calculated.
So in D32Dasm goto address 0046A0EF and enter
into that call, or you can use Ice-Dump's (/SCREENDUMP)
Be sure to Setup the ScreenDump to mode 1
How we do that??
1.Load proper VxD of Ice-Dump for your WinICE versions we can use his
/SCREENDUMP utile
2.press /SCREENDUMP until u will see <MODE 1> (a text mode)
This will help us dump the screen seeing at WinICE.
Anyway you Remember the call i marked in YELLOW? ...No?
here:
0046A0EF CALL
00469980
This is the call that leads to the Algo of the
program (where serial is being Calculated).
Let us step into that call...what do we see in
WinICE? :
0177:00469980
PUSH EBP
0177:00469981 MOV EBP,ESP 0177:00469983 PUSH ECX 0177:00469984 PUSH EBX 0177:00469985 PUSH ESI 0177:00469986 MOV [EBP-04],EAX ; EBP-04 = 'Bengaly' <= Name 0177:00469989 XOR EBX,EBX ; EBX = 0 (counter to 20 ?) 0177:0046998B MOV EAX,[EBP-04] ; EAX = name 0177:0046998E CALL 00403BD0 ; put "10 commanders" 0177:00469993 MOV EDX,EAX ; EDX = 14h (20dec) means 20 grocerys 0177:00469995 TEST EDX,EDX ; is it really 20? 0177:00469997 JLE 004699CE ; no? than Jump, Else continue 0177:00469999 MOV ECX,00000001 ; ECX = 1 0177:0046999E MOV EAX,[EBP-04] ; EAX = 'Bengaly' 0177:004699A1 MOVZX EAX,BYTE PTR [ECX+EAX-01] ; mov first char from 'Bengaly' to EAX 0177:004699A6 SHL EBX,04 ; shift Left 4 in EBX (4<<0 bytes = 0) 0177:004699A9 ADD EAX,EBX ; EAX ('B') + EBX (0) = 'B' 0177:004699AB JNO 004699B2 ; Jump Not Overflow <==| 0177:004699AD CALL 00402DC8 ; | 0177:004699B2 MOV EBX,EAX ; EBX = 'B' <=====| 0177:004699B4 MOV EAX,EBX ; EAX = 'B' 0177:004699B6 AND EAX,0F000000 ; B AND 0FFFFFFF = 0 0177:004699BB TEST EAX,EAX ; Eax = 0 ? 0177:004699BD JZ 004699C6 ; yes..Jump <=========| 0177:004699BF MOV ESI,EAX ; ESI = 0 | 0177:004699C1 SHR ESI,18 ; 0>>18 | 0177:004699C4 XOR EBX,ESI ; 'B' Xor 0 | 0177:004699C6 NOT EAX ; 0 NOT = FFFFFFFF <===| 0177:004699C8 AND EBX,EAX ; 'B' AND FFFFFFFF = 'B' 0177:004699CA INC ECX ; Next Char ('e') 0177:004699CB DEC EDX ; EDX = 13h (19 Dec) Counter 20->0 0177:004699CC JNZ 0046999E ; While not finished Counter: MOV EAX,[EBP-04] 0177:004699CE MOV EAX,EBX ; we are here from jle 004699CE 0177:004699D0 POP ESI ; Restore ESI 0177:004699D1 POP EBX ; Restore EBX 0177:004699D2 POP ECX ; Restore ECX 0177:004699D3 POP EBP ; Restore EBP 0177:004699D4 RET ; Return (out of this call) |
What
the algo do is pretty Simple in Away:
1.get
the name
2.name+
"10 commanders" (add the string to the name)
3.Get
length
4.loop
(do while not zero, type of loop) so the loop will get every Char from
the name you entered and do the flowing loop
Until
it will reach to the last char!
5.EBX
will be the pointer where the serial will be generated and it will pass
the final serial to EAX
Now we will Delete Unnecessary asm code and Edit it so it will work
on our Keygen.
Just remember it's a LOOP so you will need to add a loop statement...(you
will see in the finished ripped algo).
Look below and see which code are nunnery!
PUSH EBP
; Delete no need to push anything
MOV EBP,ESP ; Delete no need to push anything PUSH ECX ; Delete no need to push anything PUSH EBX ; Delete no need to push anything PUSH ESI ; Delete no need to push anything MOV [EBP-04],EAX ; Delete we already got the Name from the input box XOR EBX,EBX MOV EAX,[EBP-04] ; Delete ne need to move name CALL 00403BD0 ; Delete we already got what it does "10 commendats" string MOV EDX,EAX TEST EDX,EDX ; Delete no tests JLE 004699CE ; Delete no jumps MOV ECX,00000001 MOV EAX,[EBP-04] ; Delete, No need to move the name again MOVZX EAX,BYTE PTR [ECX+"Put here Enter Buffer"-01] SHL EBX,04 ADD EAX,EBX JNO 004699B2 ; Delete No jumps CALL 00402DC8 ; Delete No need this call anymore MOV EBX,EAX MOV EAX,EBX AND EAX,0F000000 TEST EAX,EAX ; Delete we don't need Tests JZ 004699C6 ; Delete no Jumps MOV ESI,EAX SHR ESI,18 XOR EBX,ESI NOT EAX AND EBX,EAX INC ECX DEC EDX JNZ 0046999E ; Delete MOV EAX,EBX POP ESI ; Delete no need to pop POP EBX ; Delete no need to pop POP ECX ; Delete no need to pop POP EBP ; Delete no need to pop RET ; Delete no need to pop |
Only thing to left is to Delete Unnecery Code so we can add it properly
to the ASM code and to make it
A working algo so it could generate the proper Serial from Our Name.
The Edited Algo is HERE
Now
we must code the Interface of our KeyGen, download Resource Builder from:
HERE
After
you downloaded the program, extract the zip and install the program.
Run
the program [we won't need to register it now ;D maybe in another Strainer
we will]
Choose
'DIALOG' Right click and press 'ADD'
Now
we will get a blank window handle.
something
like that:
_______________________________________________
|_Tools_____________________________________
[x]_|
|
|
|
|
[<- ] [ok] [A] [ab] [O] [=] [=] [--] | V OK
( / ) Cancel l
|__________________________
_|_________________ |
_________________________
___________________________
|Dialog______________
[ X_]_| |Propeties
[ X ] |
|
| |
|
|
| |
|
|
| |
|
|_______________________
_| |
|
|_Caption_: |______ _______ __|
| Control ID:|
|
Nice pic eh ? :=)
Any way, Our KeyGen need to have 2 edit boxes + 2 button (or 3 if u
wish,1 for about button :=) + 2 texts )
So our Dialog should look like this now:
______________________________
|Dialog______________________
[ X_] _|
|
___________________
|
|
name [___________________]
|
|
_ __________________
|
|
serial [___________________]
|
|
|
|
[Generate] [Exit] [About]
|
|____________
___________________ _|
Every
Button or Text Edit has a Specific Control ID Number.
Meaning the 'Generate Button' will have: xxx number that we will call
it in the ASM code.
It goes the same as the other controls in the Dialog.
Ok after you finished to create your Keygen Interface, we will save
it as : Rsrc.rc (i.e.: Resource.rc)
Save it in the dir where you will put your asm file (better in Masm
dir: c:\masm6\Rsrc.rc)
Now don't exit 'Resource Builder yet, we need to remember which ID
number every item has..so keep it open.
Now we will make the ASM code it self.
We will start by Declaring the Machine/Import instruction, see Below:
;-----------Import
Declarations-----------------
.386 .Model flat, StdCall option casemap: none include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\gdi32.inc include \masm32\include\advapi32.inc include \masm32\include\windows.in includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\gdi32.lib includelib \masm32\lib\advapi32.lib |
We can probably Delete some Lib files but that is not the metter here.
Now we will Declair Variables to our KeyGen's ASM code..Here:
;-----------------------Variables--------------------------------------
.Data PlzMore db "1 or more chars needed to create the serial!!",0 WindowName db "MainWindow",0 ClassName db "Bengaly",0 Lengthy dd 00 Buffy db "10 Commandments",0 Entered db 40h dup (?) AboutT db "This Is My First Keygenerator Crated In Win32ASM",0 AboutC db " Grocery Companion KeyGenerator 1.2 ",0 ToDecimal db "%d",0 MyS db 15 dup (?) |
Now we will put an Unintialized Data for later use:
;-----UnIntialized Variables--
.Data? hInstance HINSTANCE ? |
After we Define the variables to use in our program, we will need a
code to create the window it self
Even if made a resource, the resource only put the ID controls and
define them while compile.
Window Code (could be copy&paste in any win32asm program) Here:
;--------------------------------------Window
Code/Hadlers--------------------------------------------
.Code Start: invoke GetModuleHandle, NULL mov hInstance,eax WinMain proc hInst:HINSTANCE LOCAL wc:WNDCLASSEX LOCAL msg:MSG LOCAL hwnd:HWND mov wc.cbSize, SIZEOF WNDCLASSEX mov wc.style, CS_HREDRAW + CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra, NULL mov wc.cbWndExtra, DLGWINDOWEXTRA push hInst pop wc.hInstance mov wc.hbrBackground, COLOR_WINDOW mov wc.lpszMenuName, NULL mov wc.lpszClassName, offset ClassName invoke LoadIcon, hInstance, NULL mov wc.hIcon, eax mov wc.hIconSm, eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax invoke RegisterClassEx, addr wc invoke CreateDialogParam, hInstance, addr WindowName, NULL, NULL, NULL mov hwnd, eax invoke UpdateWindow, hwnd .WHILE TRUE invoke GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax) invoke IsDialogMessage, hwnd, ADDR msg .if eax==FALSE invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg .endif .ENDW mov eax,msg.wParam ret WinMain endp WndProc proc hwnd:HWND ,uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg==WM_DESTROY invoke PostQuitMessage,NULL |
Ok so we have created the window with the button (Rsrc.rc remember?)
Now we need to tell the asm code what each button will do.
Here we fo that:
;---------------------Exit Button-------------------
.ELSEIF uMsg==WM_COMMAND mov eax, wParam push eax shr eax, 16 .If eax==BN_CLICKED pop eax .If eax==109 invoke ExitProcess,NULL .endif .endif .endif |
And another Button:
;------------------------About
Button--------------------------------
.IF uMsg==WM_COMMAND mov eax, wParam push eax shr eax, 16 .If eax==BN_CLICKED pop eax .If eax==112 invoke MessageBox,NULL,addr AboutT,addr AboutC,MB_OK .endif .endif |
And the last button, the Important one (the Generate button):
;-------------------------Generate
Button------------------------------
.IF uMsg==WM_COMMAND mov eax, wParam push eax shr eax, 16 .If eax==BN_CLICKED pop eax .If eax==108 invoke GetDlgItemText,hwnd,106,addr Entered, 40h cmp eax,0 jz bad jmp @endlength bad: invoke MessageBox,NULL,addr PlzMore,addr AboutC,MB_OK ret |
Now while we press the Generate button the above code will be Executed :
;----------------Riped&Edited ALGP--------------------
@endlength:
|
And we finish with the last code:
;-------------End windowProc
Definition--------
.ELSE invoke DefWindowProc,hwnd,uMsg,wParam,lParam ret .ENDIF xor eax,eax ret WndProc endp end Start |
Compile the program and see the result . (there might be 1 problem if
it will ask you about: Resource.h / Rsrc.res)..
But that is not the point, the point is that u would be able to know
how to code the KeyGen, finding the files i said above is easy
You can get help in #win32asm at Efnet.
Job Done.
|
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.
+SandMan...
|
I would like to say thank you to all who has supported me, and helped
me through my cracking days:
|
For his Great Essays And Skills |
|
For his awesome Tutorials |
|
For Help Me in Cracking & Hosting |
|
For Help Me in Win32Asm |
|
For Help Me in Win32Asm |