zapline转载CM(第十一天)分析
本帖最后由 hflywolf 于 2009-3-4 19:18 编辑zapline转载CM(第十一天)分析
【文章标题】: zapline转载CM(第十一天)分析
【文章作者】: hflywolf
【作者邮箱】: 95192939@qq.com
【下载地址】: http://www.52pojie.cn/thread-18703-1-1.html
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
-----------------------------------------------------------------
【详细过程】
嘿嘿,到这会见没大牛分析,小菜就现丑一下好了。
CM无壳,汇编写的.
OD载入CM
获取程序的句柄
00401000 > $6A 00 push 0 ; /pModule = NULL
00401002 .E8 87020000 call <jmp.&KERNEL32.GetModuleHandleA> ; \GetModuleHandleA
00401007 .A3 AB214000 mov dword ptr , eax ; 将获取的程序句柄保存到4021AB地址空间
载入图标
0040100C .C705 34214000>mov dword ptr , 4003
00401016 .C705 38214000>mov dword ptr , 004010AB
00401020 .C705 3C214000>mov dword ptr , 0
0040102A .C705 40214000>mov dword ptr , 0
00401034 .A1 AB214000 mov eax, dword ptr ; 从4021AB地址空间取出程序句柄保存到eax
00401039 .A3 44214000 mov dword ptr , eax
0040103E .6A 01 push 1 ; /RsrcName = 1.
00401040 .50 push eax ; 程序句柄(hInstance)
00401041 .E8 38030000 call <jmp.&USER32.LoadIconA> ; \LoadIconA
00401046 .A3 48214000 mov dword ptr , eax ; 将图标句柄保存到402148地址空间
载入光标
0040104B .68 007F0000 push 7F00 ; /RsrcName = IDC_ARROW
00401050 .6A 00 push 0 ; |hInst = NULL
00401052 .E8 33030000 call <jmp.&USER32.LoadCursorA> ; \LoadCursorA
00401057 .A3 4C214000 mov dword ptr , eax ; 将光标句柄保存到40214C地址空间
创建模态对话框
0040105C .6A 00 push 0 ; /lParam = NULL
0040105E .68 CE104000 push 004010CE ; |DlgProc = due-cm4.004010CE
00401063 .6A 00 push 0 ; |hOwner = NULL
00401065 .6A 01 push 1 ; |pTemplate = 1
00401067 .FF35 AB214000 push dword ptr ; |hInst = NULL
0040106D .E8 88020000 call <jmp.&USER32.DialogBoxParamA> ; \DialogBoxParamA
00401072 .EB 53 jmp short 004010C7 ; 跳到4010C7
消息循环
00401074 >6A 00 push 0 ; /MsgFilterMax = 0
00401076 .6A 00 push 0 ; |MsgFilterMin = 0
00401078 .6A 00 push 0 ; |hWnd = NULL
0040107A .68 18214000 push 00402118 ; |pMsg = due-cm4.00402118
0040107F .E8 3C030000 call <jmp.&USER32.GetMessageA> ; \GetMessageA
00401084 .66:3D 0000 cmp ax, 0 ; 如果GetMessageA函数接受到WM_QUIT消息后,退出消息循环。
00401088 .74 16 je short 004010A0 ; 跳向退出代码
0040108A .68 18214000 push 00402118 ; /pMsg = WM_NULL
0040108F .E8 80030000 call <jmp.&USER32.TranslateMessage> ; \TranslateMessage
00401094 .68 18214000 push 00402118 ; /pMsg = WM_NULL
00401099 .E8 6E020000 call <jmp.&USER32.DispatchMessageA> ; \DispatchMessageA
0040109E .^ EB D4 jmp short 00401074 ; 消息循环
退出
004010A0 >FF35 20214000 push dword ptr ; /ExitCode = 0
004010A6 .E8 19020000 call <jmp.&KERNEL32.ExitProcess> ; \ExitProcess
消息处理函数
004010B4|>FF75 14 push dword ptr ; /lParam
004010B7|.FF75 10 push dword ptr ; |wParam
004010BA|.FF75 0C push dword ptr ; |Message
004010BD|.FF75 08 push dword ptr ; |hWnd
004010C0|.E8 F5020000 call <jmp.&USER32.DefWindowProcA> ; \DefWindowProcA
提示注册成功
004010D7 > /68 00200000 push 2000 ; /Style = MB_OK|MB_TASKMODAL
004010DC . |68 01204000 push 00402001 ; |Title = "Duelist's Crackme #4"
004010E1 . |68 61204000 push 00402061 ; |Text = "Congratulations! Please send your keygen (working one) to duelist@beer.com!"
004010E6 . |6A 00 push 0 ; |hOwner = NULL
004010E8 . |E8 79020000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
取name长度,如果name为空或大于8位跳到40121A提示错误
00401127 >6A 00 push 0 ; /lParam = 0
00401129 .6A 00 push 0 ; |wParam = 0
0040112B .6A 0E push 0E ; |Message = WM_GETTEXTLENGTH
0040112D .6A 03 push 3 ; |ControlID = 3
0040112F .FF75 08 push dword ptr ; |hWnd
00401132 .E8 41020000 call <jmp.&USER32.SendDlgItemMessageA>; \SendDlgItemMessageA
00401137 .A3 AF214000 mov dword ptr , eax
0040113C .83F8 00 cmp eax, 0
0040113F .0F84 D5000000 je 0040121A
00401145 .83F8 08 cmp eax, 8
00401148 .0F8F CC000000 jg 0040121A
取code长度,如果code为空或不等于name长度则跳向40121A提示错误
0040114E .8BF0 mov esi, eax
00401150 .6A 00 push 0 ; /lParam = 0
00401152 .6A 00 push 0 ; |wParam = 0
00401154 .6A 0E push 0E ; |Message = WM_GETTEXTLENGTH
00401156 .6A 04 push 4 ; |ControlID = 4
00401158 .FF75 08 push dword ptr ; |hWnd
0040115B .E8 18020000 call <jmp.&USER32.SendDlgItemMessageA>; \SendDlgItemMessageA
00401160 .83F8 00 cmp eax, 0
00401163 .0F84 B1000000 je 0040121A
00401169 .3BF0 cmp esi, eax
0040116B .0F85 A9000000 jnz 0040121A
取name的值,放到402160地址空间中
00401171 .68 60214000 push 00402160 ; /lParam = 402160
00401176 .6A 08 push 8 ; |wParam = 8
00401178 .6A 0D push 0D ; |Message = WM_GETTEXT
0040117A .6A 03 push 3 ; |ControlID = 3
0040117C .FF75 08 push dword ptr ; |hWnd
0040117F .E8 F4010000 call <jmp.&USER32.SendDlgItemMessageA>; \SendDlgItemMessageA
取code的值,放到402179地址空间中
00401184 .68 79214000 push 00402179 ; /lParam = 402179
00401189 .6A 10 push 10 ; |wParam = 10
0040118B .6A 0D push 0D ; |Message = WM_GETTEXT
0040118D .6A 04 push 4 ; |ControlID = 4
0040118F .FF75 08 push dword ptr ; |hWnd
00401192 .E8 E1010000 call <jmp.&USER32.SendDlgItemMessageA>; \SendDlgItemMessageA
先判断name的值的合法性。
1、name只能是字母,不能为其它字符。如果不合法就跳到40121A提示错误
2、如果name中含小写字母就转大写.
再依次取name的值,如果取完就跳到4011DB判断注册码
00401197 .B9 FFFFFFFF mov ecx, -1
0040119C >41 inc ecx
0040119D .0FBE81 602140>movsx eax, byte ptr
004011A4 .83F8 00 cmp eax, 0 ;Switch (cases 0..7A)
004011A7 .74 32 je short 004011DB
004011A9 .BE FFFFFFFF mov esi, -1
004011AE .83F8 41 cmp eax, 41
004011B1 .7C 67 jl short 0040121A
004011B3 .83F8 7A cmp eax, 7A
004011B6 .77 62 ja short 0040121A
004011B8 .83F8 5A cmp eax, 5A
004011BB .7C 03 jl short 004011C0
004011BD .83E8 20 sub eax, 20 ;Cases 5A ('Z'),5B ('['),5C ('\'),5D (']'),5E ('^'),5F ('_'),60 ('`'),61 ('a'),62 ('b'),63 ('c'),64 ('d'),65 ('e'),66 ('f'),67 ('g'),68 ('h'),69 ('i'),6A ('j'),6B ('k'),6C ('l'),6D ('m')... of switch 004011A4
402017-402039地址的值是对应name的表:A1LSK2DJF4HGP3QWO5EIR6UTYZ8MXN7CBV9。记为表a
40203C-40205E地址的值是对应code的表:SU7CSJKF09NCSDO9SDF09SDRLVK7809S4NF。记为表b
首先将name各位的值与表a中的值对照,记下表a中值所在位置的序号
然后根据所得的序号在表b对应的位置查找,将得到的字符依次连接就是真code.
最后将真code保存到402194地址空间,用于与输入的code比较.
004011C0 >46 inc esi ;Cases 41 ('A'),42 ('B'),43 ('C'),44 ('D'),45 ('E'),46 ('F'),47 ('G'),48 ('H'),49 ('I'),4A ('J'),4B ('K'),4C ('L'),4D ('M'),4E ('N'),4F ('O'),50 ('P'),51 ('Q'),52 ('R'),53 ('S'),54 ('T')... of switch 004011A4
004011C1 .0FBE96 172040>movsx edx, byte ptr
004011C8 .3BC2 cmp eax, edx
004011CA .^ 75 F4 jnz short 004011C0
004011CC .0FBE86 3C2040>movsx eax, byte ptr
004011D3 .8981 94214000 mov dword ptr , eax
004011D9 .^ EB C1 jmp short 0040119C
比较code,如果输入的code为真则跳向4010D7提示注册成功,否则跳向40121A提示错误.
004011DB >FF35 AF214000 push dword ptr ;Case 0 of switch 004011A4
004011E1 .68 94214000 push 00402194
004011E6 .68 79214000 push 00402179
004011EB .E8 54000000 call 00401244
004011F0 .83F8 01 cmp eax, 1
004011F3 .^\0F84 DEFEFFFF je 004010D7
004011F9 .EB 1F jmp short 0040121A
提示错误
0040121A >68 00200000 push 2000 ; /Style = MB_OK|MB_TASKMODAL; Default case of switch 004011A4
0040121F .68 01204000 push 00402001 ; |Title = "Duelist's Crackme #4"
00401224 .68 AE204000 push 004020AE ; |Text = "Your registration info is invalid... Note that most of the special chars may raise registration problems!"
00401229 .6A 00 push 0 ; |hOwner = NULL
0040122B .E8 36010000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
注册码比较
0040124D|.8B7D 08 mov edi, dword ptr
00401250|.8B75 0C mov esi, dword ptr
00401253|.8B4D 10 mov ecx, dword ptr
00401256|.F3:A6 repe cmps byte ptr es:, byte ptr>
00401258|.67:E3 05 jcxz short 00401260
0040125B|.B8 00000000 mov eax, 0
总结:
1、用户名位数在1-8位之间
2、用户名不能为数字或其他字符,只能为26个英语字母
3、用户名如果为小写要转换成大写
4、作者在CM程序中初始化了两张数据表.
a)、对应用户名的表为表a,表a="A1LSK2DJF4HGP3QWO5EIR6UTYZ8MXN7CBV9"
b)、对应注册码的表为表b.表b="SU7CSJKF09NCSDO9SDF09SDRLVK7809S4NF"
根据name各位的值在表a中的位置,在表b中相应位置查找字符,依次将字符连接就是注册码.
附上E语言写的注册机代码:
.版本 2
.子程序 _按钮1_被单击
.参数 功能键状态, 整数型
.局部变量 name, 文本型
.局部变量 lenN, 整数型
.局部变量 code, 文本型
.局部变量 I, 整数型
.局部变量 临时变量, 整数型
.局部变量 代码变量, 文本型
name = 到大写 (编辑框1.内容)
lenN = 取文本长度 (name)
.变量循环首 (1, lenN, 1, I)
临时变量 = 取代码 (name, I)
.如果真 (临时变量 ≥ 48 且 临时变量 ≤ 57) 'name不能为数字
编辑框2.内容 = “用户名非法,只能是字母”
返回 ()
.如果真结束
.如果真 (临时变量 < 65 或 临时变量 > 90) 'name不能为除了英文字母以外的字符
编辑框2.内容 = “用户名非法,只能是字母”
返回 ()
.如果真结束
代码变量 = 取文本中间 (name, I, 1)
.判断开始 (代码变量 = “A” 或 代码变量 = “C” 或 代码变量 = “K” 或 代码变量 = “O” 或 代码变量 = “P”)
code = code + “S”
.判断 (代码变量 = “B”)
code = code + “4”
.判断 (代码变量 = “D”)
code = code + “K”
.判断 (代码变量 = “E” 或 代码变量 = “J”)
code = code + “F”
.判断 (代码变量 = “F” 或 代码变量 = “I” 或 代码变量 = “N”)
code = code + “0”
.判断 (代码变量 = “G” 或 代码变量 = “S”)
code = code + “C”
.判断 (代码变量 = “H” 或 代码变量 = “V”)
code = code + “N”
.判断 (代码变量 = “L” 或 代码变量 = “M”)
code = code + “7”
.判断 (代码变量 = “Q”)
code = code + “O”
.判断 (代码变量 = “R” 或 代码变量 = “W”)
code = code + “9”
.判断 (代码变量 = “T”)
code = code + “R”
.判断 (代码变量 = “U”)
code = code + “D”
.判断 (代码变量 = “X”)
code = code + “8”
.判断 (代码变量 = “Y”)
code = code + “L”
.判断 (代码变量 = “Z”)
code = code + “V”
.默认
code = “无法生成注册码”
.判断结束
.变量循环尾 ()
编辑框2.内容 = code
忘记把注册机传上来的:(补上下载地址)
http://zdd1wg.bay.livefilestore.com/y1p7ZOUuABcrmPhVadpbuZX3kvhD8l6FxaxkIL-Ou-ox6RHsIKhKXblR8ZlqIZHq3iGadjSk7EILz74riPZC_CzHg/KeyGen.rar?download
[ 本帖最后由 hflywolf 于 2009-2-7 14:07 编辑 ] 好详细哈。。。。呵呵。。。学习下。。。。 zhu ce ji bi wo xie de hao! hflywolf分析的很详细!等版主加精鼓励!
页:
[1]