首页
社区
课程
招聘
[原创]WIN32汇编Crackme(适合新手深入了解windows消息机制等基础知识)
发表于: 2013-11-2 23:52 12071

[原创]WIN32汇编Crackme(适合新手深入了解windows消息机制等基础知识)

2013-11-2 23:52
12071
Crackme有以下几大特点:
        1,由于是纯win32汇编语言编写,反汇编代码几乎和源代码一样,
特别适合新手分析.
        2,”麻雀虽小,五脏俱全”Crackme以对话框为主窗口(模态),虽然没有
自己的消息循环结构(此时是系统内建),但消息处理过程也是很典型的.
        3,新手会”惊奇”的发现,搜索不到字符串,==||,但是鉴于程序太小,随便往上翻看就看到了,
对!字符串”变成”资源载入使用,一般的软件开发都是这样做的….,没有用到
GetWindowText,GetDlgItemText一类的函数来获取文本编辑框的内容….
        4,双线程编程.我把消息处理过程与验证过程分开在两个线程里
        5,算法比较简单….希望有人把注册机源码贴上来
        6,外带一点ReserveMe,请把serial的长度由15改为30及以上…

不久后我将贴上汇编源码…..代码不足之处请不吝指出,谢谢:
竟然忘记限制serial的最小长度.....已修改

以下是汇编源码:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                .386
                .model flat,stdcall
                option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
include                windows.inc
include                gdi32.inc
includelib        gdi32.lib
include                user32.inc
includelib        user32.lib
include                kernel32.inc
includelib        kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;equ 等值定义
DLG_MAIN equ 1
IDC_EDIT equ 2
IDC_STC equ 3
IDC_Button_Try equ 4
IDC_Button_ABOUT equ 5
C_ICO equ 6

szUnRegInfo equ 100
szUnRegCap equ 101
szRegedInfo equ 102
szRegedCap equ 103
szAbout equ 104
szAboutCap equ 105
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
                .data?
hInstance dd ?
hIcon dd ?
hEdit dd ?
szRegBuff db 100 dup(?)
szInfoBuff db 80 dup(?)
szInfoCapBuff db 20 dup(?)
zRegLenth db ?
boolJudge db ?  ;全局标志变量
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
                .code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;注册判断
_RegJudge proc uses ebx esi edi,_lParam
LOCAL CmpLenth: byte      ;局部变量的申明,要特别注意它是用ebp当作指针存储的
pushad
mov ebx,offset szRegBuff
mov ebp,offset szRegBuff ;输入字符缓冲区地址
movzx eax,zRegLenth
movzx edx,zRegLenth  ;字符长度
.if eax >=6      ;--------------------------------算法区
mov esi,edx
mov ecx,2
div cl
.if ah!=0
        add al,1
        movzx ecx,al
        mov CmpLenth,al
        mov al,byte ptr [ebx+1]
        mov byte ptr [ebp+edx],al
        .else
                movzx ecx,al
                mov CmpLenth,al
                sub esi,1
.endif
xor eax,eax
push ebp     ;-------------------注意,ebp入栈,不然等会儿用到局部变量时候会出大问题,当然也要注意堆栈平衡
.while ecx>=1
        movzx edx,byte ptr [ebx]
        movzx edi,byte ptr [ebp+esi]
        xor edx,edi
        add eax,edx
        imul eax,ecx
        inc ebx
        dec ebp       ;-----------此处更改了ebp
        dec ecx
.endw

.if eax==102 || eax==345 || eax==235
        mov boolJudge,TRUE
.else
        mov boolJudge,FALSE
.endif
pop ebp ;---------------恢复ebp以便使用局部变量
mov cl,CmpLenth
mov ebx,offset szRegBuff
mov ebp,offset szRegBuff
.while ecx>=1
        movzx edx,byte ptr [ebx]
        movzx edi,byte ptr [ebp+esi]
        .if edx==edi
                mov boolJudge,FALSE
                .break
        .endif
        inc ebx
        dec ebp
        dec ecx
.endw
.else
        mov boolJudge,FALSE
.endif    ;---------------------------------------------------------算法区
popad
ret
_RegJudge endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 窗口过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain        proc        uses ebx edi esi hWnd,uMsg,wParam,lParam ;hWnd 即为对话框句柄
LOCAL RegThreadId: dword
mov eax,uMsg
.if eax == WM_INITDIALOG
        invoke LoadIcon,hInstance,C_ICO
        mov hIcon,eax
        invoke GetDlgItem,hWnd,IDC_EDIT
        mov hEdit,eax
        invoke SendMessage,hWnd,WM_SETICON,ICON_SMALL,hIcon
.elseif eax == WM_CLOSE
        invoke EndDialog,hWnd,NULL
.elseif eax == WM_COMMAND
        movzx eax,word ptr wParam
                .if eax==IDC_EDIT ;------------文本编辑框消息
                        invoke GetDlgItem,hWnd,IDC_EDIT
                        mov hEdit,eax
                        invoke SendMessage,hEdit,EM_LIMITTEXT,15,NULL
                        invoke SendMessage,hEdit,WM_GETTEXT,30,offset szRegBuff
                        invoke SendMessage,hEdit,WM_GETTEXTLENGTH,NULL,NULL
                        mov zRegLenth,al
                        invoke CreateThread,NULL,0,offset _RegJudge,NULL,0,addr RegThreadId;-----新建算法线程
                        invoke CloseHandle,eax

                .elseif eax==IDC_Button_Try
                        .if boolJudge==FALSE
                                invoke LoadString,hInstance,szUnRegInfo,offset szInfoBuff,80
                                invoke LoadString,hInstance,szUnRegCap,offset szInfoCapBuff,20
                                invoke MessageBoxEx,hWnd,offset szInfoBuff,offset szInfoCapBuff,MB_ICONWARNING,NULL
                        .elseif boolJudge==TRUE
                                invoke LoadString,hInstance,szRegedInfo,offset szInfoBuff,80
                                invoke LoadString,hInstance,szRegedCap,offset szInfoCapBuff,20
                                invoke MessageBox,hWnd,offset szInfoBuff,offset szInfoCapBuff,MB_ICONASTERISK
                        .endif
                .elseif eax==IDC_Button_ABOUT
                        invoke LoadString,hInstance,szAbout,offset szInfoBuff,80
                        invoke LoadString,hInstance,szAboutCap,offset szInfoCapBuff,20
                        invoke MessageBeep,MB_ICONASTERISK
                        invoke MessageBox,hWnd,offset szInfoBuff,offset szInfoCapBuff,MB_DEFBUTTON2
                .endif
                               
               
.else
        mov eax,FALSE
        ret
.endif
mov eax,TRUE
ret

_ProcWinMain        endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

start:     ;程序入口
        invoke GetModuleHandle,NULL
        mov hInstance ,eax
        invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcWinMain,NULL
       
        invoke        ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                end        start

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (12)
雪    币: 3689
活跃值: (4247)
能力值: (RANK:215 )
在线值:
发帖
回帖
粉丝
2
一个可用的序列号:f

序列号可对称分为前后两段,然后连同序列号长度进行处理

0040104D  |> /0FB613        /movzx   edx, byte ptr [ebx]             ;  序列号从前面取字符HEX
00401050  |. |0FB63C2E      |movzx   edi, byte ptr [esi+ebp]         ;  序列号从后面取字符HEX
00401054  |. |33D7          |xor     edx, edi                        ;  两者XOR
00401056  |. |03C2          |add     eax, edx                        ;  结果存放到EAX
00401058  |. |0FAFC1        |imul    eax, ecx                        ;  EAX跟序列号长度相乘
0040105B  |. |43            |inc     ebx                             ;  继续从前面取字符处理
0040105C  |. |4D            |dec     ebp                             ;  继续从后面取字符处理
0040105D  |. |49            |dec     ecx                             ;  长度-1
0040105E  |> |83F9 01        cmp     ecx, 0x1
00401061  |.^\73 EA         \jnb     short 0040104D
00401063  |.  83F8 66       cmp     eax, 0x66                        ;  最终计算结果为0x66
00401066  |.  74 0E         je      short 00401076
00401068  |.  3D 59010000   cmp     eax, 0x159                       ;  或者0x159
0040106D  |.  74 07         je      short 00401076
0040106F  |.  3D EB000000   cmp     eax, 0xEB                        ;  或者0xEB
00401074  |.  75 09         jnz     short 0040107F
00401076  |>  C605 D5304000>mov     byte ptr [0x4030D5], 0x1
0040107D  |.  EB 07         jmp     short 00401086
0040107F  |>  C605 D5304000>mov     byte ptr [0x4030D5], 0x0
00401086  |>  5D            pop     ebp
00401087  |.  8A4D FF       mov     cl, byte ptr [ebp-0x1]
0040108A  |.  BB 0C304000   mov     ebx, 0040300C                    ;  233444567748969
0040108F  |.  BD 0C304000   mov     ebp, 0040300C                    ;  233444567748969
00401094  |.  EB 17         jmp     short 004010AD
00401096  |>  0FB613        /movzx   edx, byte ptr [ebx]             ;  序列号前后两段中,正序和倒序的相同位置上不能有重复的字符
00401099  |.  0FB63C2E      |movzx   edi, byte ptr [esi+ebp]
0040109D  |.  3BD7          |cmp     edx, edi
0040109F  |.  75 09         |jnz     short 004010AA
004010A1  |.  C605 D5304000>|mov     byte ptr [0x4030D5], 0x0
004010A8  |.  EB 08         |jmp     short 004010B2
004010AA  |>  43            |inc     ebx
004010AB  |.  4D            |dec     ebp
004010AC  |.  49            |dec     ecx
004010AD  |>  83F9 01        cmp     ecx, 0x1
004010B0  |.^ 73 E4         \jnb     short 00401096
2013-11-3 00:32
0
雪    币: 3689
活跃值: (4247)
能力值: (RANK:215 )
在线值:
发帖
回帖
粉丝
3
ReserveMe不会,是不是可以用MASM重新建立个界面,然后把资源段提取出来,替换这个crackme的资源段就可以了?
2013-11-3 01:10
0
雪    币: 14
活跃值: (88)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
完全看不懂的说。。
2013-11-3 07:59
0
雪    币: 1556
活跃值: (883)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
5
竟然忘记限制serial的最小长度....感谢你的分析
利用SendMessage发送EM_LIMITTEXT消息限制了最大长度
因此只要修改此处即可
2013-11-3 08:23
0
雪    币: 242
活跃值: (112)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
刚打开时也是一头雾水,运行后看线程状态,只有一个线程。只有在键入时,才会看到有线程一闪而过,所以猜测键入时才创建线程进入检查算法。于是bp CreateThread断点,返回后来到代码段,看到创建线程的函数:
00401192  |.  50            push    eax            ; /pThreadId
00401193  |.  6A 00         push    0              ; |CreationFlags = 0
00401195  |.  6A 00         push    0              ; |pThreadParm = NULL
00401197  |.  68 00104000   push    00401000       ; |ThreadFunction = CrackMe.00401000
0040119C  |.  6A 00         push    0              ; |StackSize = 0
0040119E  |.  6A 00         push    0              ; |pSecurity = NULL
004011A0  |.  E8 75010000   call    <jmp.&kernel32>; \CreateThread

这样就可以定位CrackMe.00401000是我们要找的地方了。

然后就是算法分析了:
00401014  |.  0FB605 D43040>movzx   eax, byte ptr [4030D4]
0040101B  |.  0FB615 D43040>movzx   edx, byte ptr [4030D4]
00401022  |.  83F8 06       cmp     eax, 6                           ;  SN最小长度为6
00401025  |.  0F82 92000000 jb      004010BD
0040102B  |.  8BF2          mov     esi, edx
0040102D  |.  B9 02000000   mov     ecx, 2
00401032  |.  F6F1          div     cl
00401034  |.  0AE4          or      ah, ah
00401036  |.  74 10         je      short 00401048
00401038  |.  04 01         add     al, 1
0040103A  |.  0FB6C8        movzx   ecx, al
0040103D  |.  8845 FF       mov     byte ptr [ebp-1], al
00401040  |.  8A43 01       mov     al, byte ptr [ebx+1]
00401043  |.  88042A        mov     byte ptr [edx+ebp], al
00401046  |.  EB 09         jmp     short 00401051
00401048  |>  0FB6C8        movzx   ecx, al
0040104B  |.  8845 FF       mov     byte ptr [ebp-1], al
0040104E  |.  83EE 01       sub     esi, 1
00401051  |>  33C0          xor     eax, eax
00401053  |.  55            push    ebp
00401054  |.  EB 11         jmp     short 00401067
00401056  |>  0FB613        /movzx   edx, byte ptr [ebx]             ;  首尾字符XOR并累加的计算
00401059  |.  0FB63C2E      |movzx   edi, byte ptr [esi+ebp]
0040105D  |.  33D7          |xor     edx, edi
0040105F  |.  03C2          |add     eax, edx
00401061  |.  0FAFC1        |imul    eax, ecx
00401064  |.  43            |inc     ebx
00401065  |.  4D            |dec     ebp
00401066  |.  49            |dec     ecx
00401067  |>  83F9 01        cmp     ecx, 1
0040106A  |.^ 73 EA         \jnb     short 00401056
0040106C  |.  83F8 66       cmp     eax, 66                          ;  结果必须为66、159或EB
0040106F  |.  74 0E         je      short 0040107F
00401071  |.  3D 59010000   cmp     eax, 159
00401076  |.  74 07         je      short 0040107F
00401078  |.  3D EB000000   cmp     eax, 0EB
0040107D  |.  75 09         jnz     short 00401088
0040107F  |>  C605 D5304000>mov     byte ptr [4030D5], 1             ;  这个变量是成功的关键
00401086  |.  EB 07         jmp     short 0040108F
00401088  |>  C605 D5304000>mov     byte ptr [4030D5], 0
0040108F  |>  5D            pop     ebp
00401090  |.  8A4D FF       mov     cl, byte ptr [ebp-1]
00401093  |.  BB 0C304000   mov     ebx, 0040300C                    ;  ASCII "34TJ78"
00401098  |.  BD 0C304000   mov     ebp, 0040300C                    ;  ASCII "34TJ78"
0040109D  |.  EB 17         jmp     short 004010B6
0040109F  |>  0FB613        /movzx   edx, byte ptr [ebx]
004010A2  |.  0FB63C2E      |movzx   edi, byte ptr [esi+ebp]
004010A6  |.  3BD7          |cmp     edx, edi                        ;  而且首尾XOR的字符不能相等
004010A8  |.  75 09         |jnz     short 004010B3
004010AA  |.  C605 D5304000>|mov     byte ptr [4030D5], 0
004010B1  |.  EB 11         |jmp     short 004010C4
004010B3  |>  43            |inc     ebx
004010B4  |.  4D            |dec     ebp
004010B5  |.  49            |dec     ecx
004010B6  |>  83F9 01        cmp     ecx, 1
004010B9  |.^ 73 E4         \jnb     short 0040109F
004010BB  |.  EB 07         jmp     short 004010C4

在完整的软件中,给创建线程下断解决不了问题,线程很可能早就运行了,而且多个线程协同工作,在很多线程中很难判断谁是你要找的。

期待高手指点。。
2013-11-3 11:17
0
雪    币: 1556
活跃值: (883)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
7
分析的很好。的确,当多线程并行时,查找算法所在就真的是个问题了(再加上重启验证)
不知道谁能分享一下这方面的经验?
2013-11-3 13:33
0
雪    币: 71
活跃值: (286)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
我来看看我的注册时间的
2013-11-3 15:10
0
雪    币: 11096
活跃值: (17617)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
来支持汇编高手的作品
2013-11-3 15:58
0
雪    币: 111
活跃值: (219)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
上一串注册码:
上传的附件:
2013-11-4 18:47
0
雪    币: 1556
活跃值: (883)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
11
[QUOTE=pinggle;1236848]上一串注册码:

希望你是独立分析出来写的注册机....(吾爱破解上已经有人放出注册机源码)
愿意分享分析过程不?
有兴趣再把那个一点点的ReserveMe解决掉.
2013-11-4 19:01
0
雪    币: 111
活跃值: (219)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
额,吾爱的源码是我发的。关于30位以上,我想应该利用32位溢出原理,在溢出的基础上再做调整,只是这次的调整就不是之前的一位调整了,调整的数据值返回比较大,根据2的阶乘来分配...
今天以下午的时间就在弄这个注册机,晚上有点别的事情,明天有时间再继续写...
2013-11-4 20:25
0
雪    币: 1556
活跃值: (883)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
13
这样来说,那我建议你把这个Crackme分析完全(包括注册机实现原理,算法分析,消息处理过程等),写一篇独立的文章发表.
我想这样会有很多人受益的,也比较有价值.
2013-11-4 23:12
0
游客
登录 | 注册 方可回帖
返回
//