i'd like to know , if there anyone have a source for win32asm keygen with comments 4 newbies.
i think that best way to learn is get some good example.
Hello,
Here's one skeleton for, I've removed the serial generation as
it was part of the rea course. I've just post the asm, other
files are those generted by RadASM, don't think I added something
in those.....the basic template is a dialogbox.
Anyway, let me know if you need further details:
I'm using the Masm8 Hutch's package for win32 and Ketilo
RadASM as IDE.
Code:;=========================================================================== ; KeyGen by etherlord ; Compiled with RadASM/MASM32 ;=========================================================================== .386 .model flat, stdcall ;32 bit memory model option casemap :none ;case sensitive include REAKEYG1.inc .code start: invoke GetModuleHandle,NULL mov hInstance,eax invoke InitCommonControls invoke DialogBoxParam,hInstance,IDD_DIALOG1,NULL,addr DlgProc,NULL invoke ExitProcess,0 ;######################################################################## DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM mov eax,uMsg .if eax==WM_INITDIALOG .elseif eax==WM_COMMAND ; user press the generate button mov eax,wParam .IF ax==IDC_BTN1 ; getting the handle of the Crackme window with FindWindow invoke FindWindow, addr lpClassName, addr lpWindowName .if eax!=NULL ; we have found a handle mov hwndParent,eax ; now we have to get the handle of the subwindow with FindWindowsEx invoke FindWindowEx,hwndParent,hwndChildAfter, addr ClWindn, NULL ; if we get a handle, time to retrieve the info .if eax!=NULL mov hwindfirst,eax ; we are now seeking the second textbox invoke FindWindowEx,hwndParent,hwind, addr ClWindn, NULL .if eax!=NULL mov hwind,eax invoke SendMessage,hwind,WM_GETTEXT,wParam,addr TexBuf .if eax!=NULL ;we got some chars in the buffer, placing them back ; to our windows, invoke SetDlgItemTextA,hWin,IDC_EDT1,addr TexBuf ; Now, we have to build the correct serial from it pushad ; code removed from here... just serial generation ; then we print out the result invoke SetDlgItemTextA,hWin,IDC_EDT2,addr HrdCodStr popad .endif .endif .endif ;invoke MessageBox,NULL,addr MsgBoxText, addr MsgBoxCaption, MB_OK .endif .endif .elseif eax==WM_CLOSE invoke EndDialog,hWin,0 .else mov eax,FALSE ret .endif mov eax,TRUE ret DlgProc endp end start
Hi achi,
I agree with you about the fact that the best way to learn is to start from some good example but we also need a bit of theory. To learn how to keygen a program, you have only to understand how the name/serial routine works. After that, when you know how the routine works, if you want to write a keygenerator you have to know how to write a simple program, in assembly or c or in the language you like.
The source posted by FoolFox is correct but if you want to learn how to write a program, take a look at Iczelion's site: http://win32asm.cjb.net/
The tutorial section contains interesting tutorials on how to write win32 applications.
Tell us if to write a win32 application is really what you want to learn, we could leave this thread for all those whom want to learn how to write a simple application (or a keygenerator template ;-))
ZaiRoN
Hello,
Yeah, Zairon is right, maybe I was a little bit straightforward on
this one
just in case, here's some details on the keygen I'had made
a while ago for a friend, it's just some notes on why the
sample is done this way :
But the main point, is the one shown by Zairon, that you needCode:So, step by step : - Find the handle of the application. - Find the handle of the textbox where the name lie. - Retrieve the content of the username textbox. - Compute the correct serial. - Either show the user the correct serial or inject it directly in the application. To find the handle of the application, I use WinSpector, there is many tools of that kind floating around, any that'll show you the handle, class, and such info will do the job. What we need to find the handle of the application is the window name and the class name. Once found we are ready to start our keygen. To find the handle of the application windows, we'll use the FindWindow API. The FindWindow API need the following params: Syntax HWND FindWindow( LPCTSTR lpClassName, LPCTSTR lpWindowName ); Parameters lpClassName ----------- [in] Pointer to a null-terminated string that specifies the class name or a class atom created by a previous call to the RegisterClass or RegisterClassEx function. The atom must be in the low-order word of lpClassName; the high-order word must be zero. If lpClassName points to a string, it specifies the window class name. The class name can be any name registered with RegisterClass or RegisterClassEx, or any of the predefined control-class names. If lpClassName is NULL, it finds any window whose title matches the lpWindowName parameter. lpWindowName ------------ [in] Pointer to a null-terminated string that specifies the window name (the window's title). If this parameter is NULL, all window names match. Return Value ------------ If the function succeeds, the return value is a handle to the window that has the specified class name and window name. If the function fails, the return value is NULL. To get extended error information, call GetLastError. So, to get the handle, we'll use the function the following way : includelib user32.lib FindWindow PROTO lpClassName:HWND,lpWindowName:HWND .data lpClassName db "<ClassName>",0 lpWindowName db "<WindowName>",0 hwndParent dd ? .code ...... .IF ax==IDC_BTN1 ; getting the handle of the window with FindWindow invoke FindWindow, addr lpClassName, addr lpWindowName .if eax!=NULL ; if we get a result, store the result handle mov hwndParent,eax We have now the window handle stored in hwndParent. From there, we must find the child window, the one wich handle the textbox. In case we have several textbox, we may need to enumerate them until we got the good one. Those objects are declared in ressources, kind of static object, once you got a value about them this value should not change. To find the handle of the child window, we can use the FindWindowsEx function. Syntax HWND FindWindowEx( HWND hwndParent, HWND hwndChildAfter, LPCTSTR lpszClass, LPCTSTR lpszWindow ); Parameters hwndParent ---------- [in] Handle to the parent window whose child windows are to be searched. If hwndParent is NULL, the function uses the desktop window as the parent window. The function searches among windows that are child windows of the desktop. hwndChildAfter -------------- [in] Handle to a child window. The search begins with the next child window in the Z order. The child window must be a direct child window of hwndParent, not just a descendant window. If hwndChildAfter is NULL, the search begins with the first child window of hwndParent. Note that if both hwndParent and hwndChildAfter are NULL, the function searches all top-level and message-only windows. lpszClass --------- [in] Pointer to a null-terminated string that specifies the class name or a class atom created by a previous call to the RegisterClass or RegisterClassEx function. The atom must be placed in the low-order word of lpszClass; the high-order word must be zero. If lpszClass is a string, it specifies the window class name. The class name can be any name registered with RegisterClass or RegisterClassEx, or any of the predefined control-class names, or it can be MAKEINTATOM(0x800). In this latter case, 0x8000 is the atom for a menu class. For more information, see the Remarks section of this topic. lpszWindow ---------- [in] Pointer to a null-terminated string that specifies the window name (the window's title). If this parameter is NULL, all window names match. Return Value ------------ If the function succeeds, the return value is a handle to the window that has the specified class and window names. If the function fails, the return value is NULL. To get extended error information, call GetLastError. If we consider a standard username/serial combo, the first subwindow is usually the username textbox, the one we want to catch. If we wanted to also grab a second textbox (company, or anything...), then we would have to call the function a second time. This function is called the followin way (we are assuming here that we got the hwndParent from previous call): includelib user32.lib FindWindowEx PROTO hwndParent:DWORD, hwndChildAfter:DWORD, lpszClass:HWND, lpszWindow:HWND .data ClWindn db "<TextBoxName>",0 hwndChildAfter dd ? hwindfirst dd ? .code ...... ; now we have to get the handle of the subwindow with FindWindowsEx invoke FindWindowEx,hwndParent,hwndChildAfter, addr ClWindn, NULL .if eax!=NULL ; if we get a result, store the handle mov hwindfirst,eax Ok, we have now the handle we need to retrieve the info we want. But, how could we do that ? If we where in the application, a simple WM_GETEXT would have done the job. But we are seeking the info from an external application. So we need to use Windows MESSAGES to send the command to the right application. Syntax LRESULT SendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ); Parameters hWnd ---- [in] Handle to the window whose window procedure will receive the message. If this parameter is HWND_BROADCAST, the message is sent to all top-level windows in the system, including disabled or invisible unowned windows, overlapped windows, and pop-up windows; but the message is not sent to child windows. Msg --- [in] Specifies the message to be sent. wParam ------ [in] Specifies additional message-specific information. lParam ------ [in] Specifies additional message-specific information. Return Value ------------ The return value specifies the result of the message processing; it depends on the message sent. To send the WM_GETTEXT command and retrieve the result, we'll use the following snippet : includelib user32.lib .data TexBuf db "00000000000000000",0 .code ...... ; here we are getting the handle of the textbox .if eax!=NULL ; we save the handle of the textbox mov hwind,eax ; we send the WM_GETTEXT message to the textbox ; wParam is a parameter passed to/from DlgProc invoke SendMessage,hwind,WM_GETTEXT,wParam,addr TexBuf .if eax!=NULL ; here we deal with the result found And we have now the username stored in TexBuf, ready for any kind of processing. From them, insert your algo computation and show the result to the user. We are just showing a textbox here, but we could have as well send a WM_SETTEXT command to the second textbox to fill the serial in place of the user. Just a thing to remember, before messing with register in your function, it's a good thing to save the registers. You can choose to save only those you play with, I find it easier to user the PUSHAD/POPAD function (push all 32 bits register in the stack) : .if eax!=NULL ; here we deal with the result found pushad .... your func here .... popad
first to understand the algo used in the prog you want to
keygen.
Hope this help to clear it a little bit.
Regards
FoolFox
Hi All,
thx for the explanation FoolFox :-)
To join theory and practice I will add a simple crackme to this thread. This is a simple crackme and, to keygen it, you only need to rip the original code. I decided to attach this type of crackme because I wanted to join this thread with the thread in the newbies forum named "Copying keymaker ASM from Win32Dasm" (read it, you will find a little hint :-)).
In this way the project is complete and it gives you the possibility to:
- learn to write a win32asm keygen
- learn to rip code from a program
I thought it could be an interesting idea, what do you think?
Let the discussion begin :-)
Good luck,
ZaiRoN
Hmm, interesting; can you let RadASM generate the code for loading the form and handling it automatically? Or do you still have to do it by hand? (If so, I'd rather stick with raw MASM).Originally posted by FoolFox
Hello,
Here's one skeleton for, I've removed the serial generation as
it was part of the rea course. I've just post the asm, other
files are those generted by RadASM, don't think I added something
in those.....the basic template is a dialogbox.
Anyway, let me know if you need further details:
I'm using the Masm8 Hutch's package for win32 and Ketilo
RadASM as IDE.
Code:<--snip-->
- Fahr
hello ZaiRoN & others..
this thread seems to me too iLLegalz!
2 little tech questions I inject here:
I have dlded masm8 & about 2 month fight with it..
Q1: So Masm can't MMX? or can(where to read how?)?
//
Q2: Can't force Masm to Immediate memory R/W..
e.g.
if I wrote:
mov eax, dword ptr[00402000]..
this will anyway:
mov eax, 00402000..
So not supported?
*********
DEPIH is Greyt!
Hi evaluator!
>Q1: So Masm can't MMX? or can(where to read how?)?
You can but you have to use .MMX directive.
>Q2: Can't force Masm to Immediate memory R/W..
I am not totally sure but I don't think you can work directly with virtual address... Delphi can?
For specific masm questions you can take a look at these two boards:
http://www.masmforum.com/
http://board.win32asmcommunity.net/
ZaiRoN
ye, Delpih can
mayb, better you switch from masm!?:)
"I am to old" for inject in other forums:(
Please, can you describe how put this .MMX
directive or make for me header..
(but no big prob, do DB..)
Hello,
Yeah, RadASM come with basic templates, such as dialoggbox,Originally posted by Fahr
Hmm, interesting; can you let RadASM generate the code for loading the form and handling it automatically? Or do you still have to do it by hand? (If so, I'd rather stick with raw MASM).
- Fahr
window squeletton, and the code work as is.
Of course, depending on what you want to achieve, you may
have to add some extra functionnality, handling message, and
so on. If you add a button on the ressource, you'll have to
deal accordingly in your source...
But for little projects, RadASM let you quickly do some windows
stuff...
@evaluator:
you can write the .mmx directive just before the .code directive.
Regards
FoolFox
thanx you very match!
this works, also .XMM works
I searched in HLP files about MMX but nothing found.
judge me..
"RTFM or NOT RTFM <- thiS waS a queStion!" (W.FoolFox)
Ok, I did your keygen and it came out niceOriginally posted by ZaiRoN
Hi All,
thx for the explanation FoolFox :-)
To join theory and practice I will add a simple crackme to this thread. This is a simple crackme and, to keygen it, you only need to rip the original code. I decided to attach this type of crackme because I wanted to join this thread with the thread in the newbies forum named "Copying keymaker ASM from Win32Dasm" (read it, you will find a little hint :-)).
In this way the project is complete and it gives you the possibility to:
- learn to write a win32asm keygen
- learn to rip code from a program
I thought it could be an interesting idea, what do you think?
Let the discussion begin :-)
Good luck,
ZaiRoN
Except for one little detail
For some reason, the wsprintfa doesn't produce a nice 8 digit number, instead it produces the correct serial (first 8 digits) and then keeps repeating the last 5 digits of the serial for numerous times. Anyone care to enlighten me as to what is wrong?
Here is my code and exe:
http://dump.lycantrope.com:5000/keymaker.asm
http://dump.lycantrope.com:5000/keymaker.exe
I know the name is still hardcoded, but this is only a tryout for getting the code. Once it works ok, I'll make it into a nice dialog.
- Fahr
Try changing this line:
@Buffer db 0
To this:
@Buffer db 20 dup (0h)
That way you have 20 bytes to store the serial, instead of just one![]()
First, you are defining buffer which is only 1 byte big:
@Buffer db 0
255 bytes will be more than enough:
@Buffer db 255
Second, this variable will be used for MessageBox which needs string terminated with 0 so you need to initialize this var with zero's:
@Buffer db 255 dup(0)
Now, it will work
Bookmarks