首页
社区
课程
招聘
[原创]第一次keygen详解,献给各位兄弟(申请邀请码)
发表于: 2010-10-14 23:28 13926

[原创]第一次keygen详解,献给各位兄弟(申请邀请码)

2010-10-14 23:28
13926

注册论坛一个多月,一直在坛子中观看各位年轻有才的同学们挥洒文字,激昂江山,从中学到很多东西。鄙人人笨才浅,只好一直偷偷藏拙。坛子中好多年轻的兄弟,还在学校里读书就能写出一些很有意义的东西,让人十分艳羡。想我浑浑噩噩已经工作四年,之前一直从事软件开发,8月份突然转行开做安全,在安全方面的积累跟坛子中很多兄弟相比,差距以万里计,十分汗颜。所谓知不足而后奋起追,也望各位兄弟多多提点。这是我第一次完整有条理的crackme生成keygen,虽说十分简单,但也有些许可取之处,故分享在这里。

闲话少说,言归正传。某日在看雪晃荡,看到一兄弟的一篇精华破文(围观者:砸死你,还在废话。。。。),里面提到网站http://www.crackmes.de,本人好猎奇,所以赶紧上去一观。也照葫芦画瓢,从中选了一个最近的为解决crackme,破解之。

现在真的开始,crackme下载地址:http://www.crackmes.de/users/kkr_we_rule/asm_keygen_me_2/

这个cm是用汇编写成,大小只有4096byte,麻雀虽小,五脏俱全,而且汇编代码写得十分优美,让我非常向往。我通读了他的所有.text,所以本篇破文,逐行分析其keygen过程,不涉及任何调试技巧。
用OD打开KeyGen ME - 2.exe,来到其exe程序入口:

CPU Disasm
Address   Hex dump          Command                                  Comments
00401000  /.  6A 00         PUSH 0                                   ; /ModuleName = NULL
00401002  |.  E8 A9030000   CALL <JMP.&kernel32.GetModuleHandleA>    ; \KERNEL32.GetModuleHandleA
00401007  |.  A3 E0274000   MOV DWORD PTR DS:[4027E0],EAX
0040100C  |.  6A 00         PUSH 0                                   ; /InitParam = 0
0040100E  |.  68 28104000   PUSH 00401028                            ; |DialogProc = KeyGen_ME_-_2.401028
00401013  |.  6A 00         PUSH 0                                   ; |hParent = NULL
00401015  |.  6A 65         PUSH 65                                  ; |TemplateName = 65
00401017  |.  FF35 E0274000 PUSH DWORD PTR DS:[4027E0]               ; |hInst = 00400000 ('KeyGen_ME_-_2')
0040101D  |.  E8 76030000   CALL <JMP.&user32.DialogBoxParamA>       ; \USER32.DialogBoxParamA
00401022  |.  50            PUSH EAX                                 ; /ExitCode
00401023  |.  E8 8E030000   CALL <JMP.&kernel32.ExitProcess>         ; \KERNEL32.ExitProcess
Address   Hex dump          Command                                  Comments
00401028  |$  55            PUSH EBP
00401029  |.  8BEC          MOV EBP,ESP
0040102B  |.  817D 0C 11010 CMP DWORD PTR SS:[ARG.2],111             ; 非WM_COMMAND跳转
00401032  |.  75 1C         JNE SHORT 00401050
00401034  |.  817D 10 EB030 CMP DWORD PTR SS:[ARG.3],3EB             ; validate按钮ID=1003
0040103B  |.  75 23         JNE SHORT 00401060
0040103D  |.  FF75 08       PUSH DWORD PTR SS:[ARG.1]                ; /Arg1 => [ARG.1]
00401040  |.  E8 21000000   CALL 00401066                            ; \KeyGen_ME_-_2.00401066
00401045  |.  6A 00         PUSH 0
00401047  |.  6A 00         PUSH 0
00401049  |.  E8 6E030000   CALL <JMP.&kernel32.RtlZeroMemory>       ; Jump to ntdll.RtlZeroMemory
0040104E  |.  EB 10         JMP SHORT 00401060
00401050  |>  837D 0C 10    CMP DWORD PTR SS:[ARG.2],10
00401054  |.  75 0A         JNE SHORT 00401060
00401056  |.  6A 00         PUSH 0                                   ; /Result = 0
00401058  |.  FF75 08       PUSH DWORD PTR SS:[ARG.1]                ; |hDialog => [ARG.1]
0040105B  |.  E8 3E030000   CALL <JMP.&user32.EndDialog>             ; \USER32.EndDialog
00401060  |>  33C0          XOR EAX,EAX
00401062  |.  C9            LEAVE
00401063  \.  C2 1000       RETN 10
CPU Disasm
Address   Hex dump          Command                                  Comments
00401066  /$  55            PUSH EBP                                 ; KeyGen_ME_-_2.00401066(guessed Arg1)
00401067  |.  8BEC          MOV EBP,ESP
00401069  |.  68 01010000   PUSH 101                                 ; /MaxCount = 257.
0040106E  |.  68 00204000   PUSH OFFSET 00402000                     ; |String = "abcde"
00401073  |.  68 E9030000   PUSH 3E9                                 ; |ItemID = 1001.
00401078  |.  FF75 08       PUSH DWORD PTR SS:[ARG.1]                ; |hDialog => [ARG.1]
0040107B  |.  E8 24030000   CALL <JMP.&user32.GetDlgItemTextA>       ; \USER32.GetDlgItemTextA
00401080  |.  83F8 03       CMP EAX,3
00401083  |.  0F8E 88010000 JLE 00401211                             ; name长度小于等于3退出
00401089  |.  68 01010000   PUSH 101                                 ; /MaxCount = 257.
0040108E  |.  68 00214000   PUSH OFFSET 00402100                     ; |String = "123-45"
00401093  |.  68 EA030000   PUSH 3EA                                 ; |ItemID = 1002.
00401098  |.  FF75 08       PUSH DWORD PTR SS:[ARG.1]                ; |hDialog => [ARG.1]
0040109B  |.  E8 04030000   CALL <JMP.&user32.GetDlgItemTextA>       ; \USER32.GetDlgItemTextA
004010A0  |.  83F8 00       CMP EAX,0                                ; serial长度等于0时退出
004010A3  |.  0F84 68010000 JE 00401211
CPU Disasm
Address   Hex dump          Command                                  Comments
004010A9  |.  8BD8          MOV EBX,EAX
004010AB  |.  33C0          XOR EAX,EAX
004010AD  |.  33C9          XOR ECX,ECX
004010AF  |.  BE 00214000   MOV ESI,OFFSET 00402100                  ; ASCII "123"
004010B4  |>  66:0FB606     /MOVZX AX,BYTE PTR DS:[ESI]
004010B8  |.  66:83F8 2D    |CMP AX,2D                               ; 判断密码中是否存在-号
004010BC  |.  74 0A         |JE SHORT 004010C8
004010BE  |.  46            |INC ESI
004010BF  |.  41            |INC ECX
004010C0  |.  4B            |DEC EBX
004010C1  |.^ 75 F1         \JNE SHORT 004010B4
004010C3  |.  E9 33010000   JMP 004011FB
004010C8  |>  C606 00       MOV BYTE PTR DS:[ESI],0
004010CB  |.  41            INC ECX
004010CC  |.  51            PUSH ECX                                 ; /N
004010CD  |.  68 00214000   PUSH OFFSET 00402100                     ; |Src = "123"
004010D2  |.  68 00224000   PUSH OFFSET 00402200                     ; |Dest = "123"
004010D7  |.  E8 E6020000   CALL <JMP.&kernel32.lstrcpynA>           ; \KERNEL32.lstrcpynA
004010DC  |.  68 00224000   PUSH OFFSET 00402200                     ; /Src = "123"
004010E1  |.  68 00244000   PUSH OFFSET 00402400                     ; |Dest = "123"
004010E6  |.  E8 DD020000   CALL <JMP.&kernel32.lstrcpyA>            ; \KERNEL32.lstrcpyA
004010EB  |.  33C0          XOR EAX,EAX
004010ED  |.  46            INC ESI
004010EE  |.  56            PUSH ESI                                 ; /Src
004010EF  |.  68 00234000   PUSH OFFSET 00402300                     ; |Dest = "45"
004010F4  |.  E8 CF020000   CALL <JMP.&kernel32.lstrcpyA>            ; \KERNEL32.lstrcpyA
004010F9  |.  68 00234000   PUSH OFFSET 00402300                     ; /Src = "45"
004010FE  |.  68 00254000   PUSH OFFSET 00402500                     ; |Dest = "45"
00401103  |.  E8 C0020000   CALL <JMP.&kernel32.lstrcpyA>            ; \KERNEL32.lstrcpyA

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (56)
雪    币: 109
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
谢谢楼主放代码,支持获取邀请码。
2010-10-14 23:59
0
雪    币: 49
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
谢谢楼主,好好学习
2010-10-15 00:24
0
雪    币: 4
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
我怎么还在门外转悠呢.....................
2010-10-15 01:19
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
虽然看不懂,也支持楼主。。。。。。。
2010-10-15 01:25
0
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
看看,支持LZ!
2010-10-15 06:37
0
雪    币: 139
活跃值: (40)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
7
多谢大家支持~~~~~
2010-10-15 08:46
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wut
8
楼主在前进!
2010-10-15 09:20
0
雪    币: 105
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
DDDDDDDDDDDDDDDDDDDDD!
2010-10-15 16:15
0
雪    币: 63
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
cfo
10
比较的悲剧...我看不懂汇编。
2010-10-15 18:55
0
雪    币: 139
活跃值: (40)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
11
慢慢看,比高级语言难懂一点,我也是不太熟练汇编,只能看看而已,呵呵。
2010-10-15 19:14
0
雪    币: 32
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
看看,支持LZ!
2010-10-15 19:24
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
学习中。收藏了!
2010-10-16 08:41
0
雪    币: 139
活跃值: (40)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
14
这么快沉了,顶一下。
2010-10-18 08:52
0
雪    币: 30
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
学习了。。。
2010-10-18 09:02
0
雪    币: 33
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
看了话题还不知道哪里可以回复!糟糕死了
2010-10-18 23:56
0
雪    币: 35
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
看不懂,先收藏。看来还要加油学。
2010-10-19 05:47
0
雪    币: 16
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
强啊!慢慢研究…
2010-10-19 06:21
0
雪    币: 242
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
19
分析得不错,不过这个要用OD吗?。。好像用IDA Pro就已经搞定了。。那些看不懂汇编的可以试试:
__int16 __stdcall sub_401273(LPCSTR lpString)
{
  int v1; // edx@1
  __int16 v2; // bx@1
  LPCSTR v3; // esi@1

  v1 = lstrlenA(lpString);
  v3 = lpString;
  v2 = 0;
  do
  {
    v2 = (unsigned __int8)*v3 & (unsigned __int16)(((unsigned __int8)*v3 ^ (unsigned __int16)((unsigned __int8)*v3 + v2))
                                                 - (unsigned __int8)*v3);
    ++v3;
    --v1;
  }
  while ( v1 );
  return 0;
}

__int64 __stdcall sub_401222(LPCSTR lpString)
{
  __int16 v1; // dx@1
  int v2; // ebx@1
  LPCSTR v3; // esi@1
  unsigned __int16 v4; // ax@2
  __int16 v5; // dx@2
  __int16 v6; // dx@2

  v2 = lstrlenA(lpString);
  v3 = lpString;
  v1 = 0;
  do
  {
    v4 = (unsigned __int8)*v3;
    v5 = 4 * (v4 ^ v4 * (v4 + v1));
    v4 >>= 2;
    v6 = __ROR__(2 * (v4 ^ v5) - v4, 4);
    v1 = v4 ^ ((v4 ^ v6) - v4);
    ++v3;
    --v2;
  }
  while ( v2 );
  return 0i64;
}
2010-10-19 08:21
0
雪    币: 139
活跃值: (40)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
20
确实可以用IDA逆向代码,这样可以很快搞出来的。
不过这是我第一次玩cm,所以以练习为主,汇编的练习是一个很重要的目的。
还用,我弄这个cm的时候,机器上只有od, 还没下载到ida,我是OD+notepad+VC6
昨晚下载了看雪2010新年大礼包,说是里面有IDA,呵呵

2010-10-19 09:31
0
雪    币: 38
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
先顶着,加油学习中.....
2010-10-22 10:32
0
雪    币: 28
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
路过学习了
2010-10-22 11:17
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
也要进门
2010-10-22 14:40
0
雪    币: 55
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
正在学习。加油。
2010-10-22 22:07
0
雪    币: 46
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
25
学习了~~,呵呵
2010-10-25 10:48
0
游客
登录 | 注册 方可回帖
返回
//