Home    Training    Downloads    Tutorials    Arbitary    Get Fate    Proxy Info
 
Training session 33: Keygen Creation on-the-fly
Difficulty: Medium
Learn how to create a keygen on-the-fly
Creator: m101


Target: Ad Muncher v4.4
URL: http://www.admuncher.com

The first thing to do is to open up Ad Muncher and find out what is going on and how it works. Then load up procdump and dump both the exe and the dll seperately. Look at the size of the exe and the dll, the exe is only a few kbytes, but the dll is much bigger (over a hundred kbytes) and has been packed with UPX. From this we can tell that the dll is the main program and the exe is a loader. Since we are doing this on-the-fly, we wont be needing Win32DASM, but if you do, then you can now disassemble the dumped files ;)

Load up Ad Muncher, enter some bogus information. When you choose what bogus information to include, make sure it DOES NOT contain any characters by choice. This is because it will normally pass most checks on input characteristics. Also, if you were smart enough to actually READ the registration page first, you would have noticed this: 'Please enter your name and code below, the code consists of two hexadecimal numbers (ie: numbers 0-9 and letters A-F) joined with a dash.' Your serial you enter should be something like '012345-543210'. Then set a breakpoint with softice on GetWindowTextA, This means when you Click register, softice should popup. You should be in the middle of a GetDlgItemTextA call, so press F12 twice to return to Ad Muncher. If you didnt break, then you arent using Windows 2000 like i am, and you will have to just set a breakpoint on GetDlgItemTextA directly. Back in the Ad Muncher code, you should see something like this:
00751431 6A68                    push 00000068
00751433 FF7508                  push [ebp+08]
00751436 E80D0C0000              Call USER32.GetDlgItemTextA
0075143B 40                      inc eax
0075143C A33C7A4B00              mov dword ptr [004B7A3C], eax

Disable your breakpoints with 'BD *' and then trace through the code with F10 till you find anything that looks interesting. By the term 'interesting' i mean any use of tables like 'mov ecx, [eax*4+005B8A1C]' or any loops that contain a 'LODSB' or 'LODSW'. Also you may want to look for stuff like 'xor ecx, ecx ; mov eax, [ecx + 005B8A1C] ; inc ecx'. You should come upto this after a minute of searching:
:loop
LODSB
ADD ECX, EAX
ROR ECX, 08
ADD ECX, EBX
CMP AL, 00
JNZ LOOP
NOT ECX

Now if you look at the start of this function and checkout esi you will find that it contatains your username and ebx holds '00012345'. Wow, the first half of our serial and our username ;) Ad Muncher takes your serial, splits it in two, then moves the location of your username into esi, and sets the value of the first half of the serial in ebx. Next it takes a character from esi, starts a running total, rolls the register right 8h times, adds the first half of the serial in ebx to the total and then loops until all of the characters have been read. After this is NOT's the total to give the second half of the serial in ecx. To make a keygen all you have to do now is convert the routine into any language you choose and give it a little interface. You can now use Ad Muncher to create valid serials without any troubles at all, but it is better to have a seperate keygen, so have a go at making one, here is the one I created:

-------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------

;Ad Muncher v4.4 Keygen by m101 for Phrozen Crew

.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

.data
ClassName db "SimpleWinClass",0
AppName  db "Ad Muncher Keygen cracked by m101 for Phrozen Crew",0
ButtonText db "Generate Key",0
StartupString db "Please enter a name...",0
EditClassName db "edit",0
EditID equ 2
EditID2 equ 3
ButtonID equ 1
ButtonClassName db "button",0
IDM_GETTEXT equ 3
Serial2 db "FFFFFFFF"
Serial db "BADC0DE-"
buffer db 512 dup(?)



.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
hwndButton HWND ?
hwndEdit HWND ?
hwndEdit2 HWND ?
.code
start:
	invoke GetModuleHandle, NULL
	mov    hInstance,eax
	invoke GetCommandLine
	mov    CommandLine,eax
	invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
	invoke ExitProcess,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
	LOCAL wc:WNDCLASSEX
	LOCAL msg:MSG
	LOCAL hwnd:HWND
	mov   wc.cbSize,SIZEOF WNDCLASSEX
	mov   wc.style, CS_HREDRAW or CS_VREDRAW
	mov   wc.lpfnWndProc, OFFSET WndProc
	mov   wc.cbClsExtra,NULL
	mov   wc.cbWndExtra,NULL
	push  hInstance
	pop   wc.hInstance
	mov   wc.hbrBackground,COLOR_BTNFACE+1
	mov   wc.lpszMenuName,NULL
	mov   wc.lpszClassName,OFFSET ClassName
	invoke LoadIcon,NULL,IDI_APPLICATION
	mov   wc.hIcon,eax
	mov   wc.hIconSm,eax
	invoke LoadCursor,NULL,IDC_ARROW
	mov   wc.hCursor,eax
	invoke RegisterClassEx, addr wc
	INVOKE CreateWindowEx,WS_EX_CONTROLPARENT	 or DS_CENTER,ADDR ClassName,ADDR AppName,\
           WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
           CW_USEDEFAULT,345,150,NULL,NULL,\
           hInst,NULL
	mov   hwnd,eax
	invoke ShowWindow, hwnd,SW_SHOWNORMAL
	invoke UpdateWindow, hwnd
	.WHILE TRUE
		invoke GetMessage, ADDR msg,NULL,0,0
		.BREAK .IF (!eax)
		invoke TranslateMessage, ADDR msg
		invoke DispatchMessage, ADDR msg
	.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
	.ELSEIF uMsg==WM_CREATE
		invoke CreateWindowEx,WS_EX_CLIENTEDGE, ADDR EditClassName,NULL,\
                        WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or\
                        ES_AUTOHSCROLL,\
                        50,20,240,25,hWnd,EditID,hInstance,NULL
		mov  hwndEdit,eax
		invoke CreateWindowEx,WS_EX_CLIENTEDGE, ADDR EditClassName,NULL,\
                        WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or\
                        ES_AUTOHSCROLL or ES_READONLY,\
                        50,45,240,25,hWnd,EditID2,hInstance,NULL
		mov  hwndEdit2,eax
            invoke SetWindowText,hwndEdit2,ADDR StartupString 
		invoke SetFocus, hwndEdit
		invoke CreateWindowEx,NULL, ADDR ButtonClassName,ADDR ButtonText,\
                        WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\
                        80,75,180,25,hWnd,ButtonID,hInstance,NULL
		mov  hwndButton,eax
	.ELSEIF uMsg==WM_COMMAND
		mov eax,wParam
		.IF lParam==0
			.IF ax==IDM_GETTEXT
                        push edi
                        push esi
			invoke GetWindowText,hwndEdit,ADDR buffer,512
                        mov ebx, 0BADC0DEh
                        lea esi, buffer
                        xor ecx,ecx
                        
looksy:
                        lodsb
                        cmp al, 41h
                        jl looksy2
                        cmp al, 5Ah
                        jg looksy2
                        add al, 20h
looksy2:
                        add ecx,eax
                        ror ecx,08h
                        add ecx,ebx
                        cmp al, 0h
                        jnz looksy
                        not ecx
                        mov eax,ecx
                        mov [Serial2+3h],al
                        mov [Serial2+2h],ah
                        shr eax, 10h
                        mov [Serial2+1h],al
                        mov [Serial2],ah
                        lea esi, Serial2
                        xor ecx,ecx
converter:
                        xor ax,ax
                        lodsb
                        cmp ecx, 8h
                        jl conv2
                        xor al, dl
conv2:
                        shl ax, 4h
                        shr al, 4h
                        cmp al, 0ah
                        jl alpha
                        add al, 37h 
                        jmp alphanumeric
alpha:
                        add al, 30h
alphanumeric:
                        cmp ah, 0ah
                        jl alphab
                        add ah, 37h
                        jmp alphanumericb
alphab:
                        add ah, 30h
alphanumericb:
                        mov [buffer+ecx], ah
                        inc ecx
                        mov [buffer+ecx], al
                        inc ecx
                        cmp ecx, 8h
                        jl converter
                        mov [buffer+ecx], 0h
                        invoke SetWindowText,hwndEdit2,ADDR Serial 

                        pop esi
                        pop edi
			.ELSE
				invoke DestroyWindow,hWnd
			.ENDIF
		.ELSE
			.IF ax==ButtonID
				shr eax,16
				.IF ax==BN_CLICKED
					invoke SendMessage,hWnd,WM_COMMAND,IDM_GETTEXT,0
				.ENDIF
			.ENDIF
		.ENDIF
	.ELSE
		invoke DefWindowProc,hWnd,uMsg,wParam,lParam		
		ret
	.ENDIF
	xor eax,eax
	ret
WndProc endp
end start

-------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------

There you have it, five minutes to find and work out the serial routine, another ten minutes for the keygen and youve created a keygen on-the-fly in fifteen minutes!
Name

URL or Email

Message